回调方法:就是将一个方法 func2 作为参数传入另一个方法 func1 中,当 func1 执行到某一步或者满足某种条件的时候才执行传入的参数 func2
Promise 是 ES6 引入的异步编程的新解决方案。
Promise 对象三种状态:初始化、成功、失败 pending-进行中、resolved-已完成、rejected-已失败
就好像,你跟你女朋友求婚,她跟你说她要考虑一下,明天才能给你答案,这就是承诺(promise)。同时,这也是一个等待的过程(pending),然后你就等,等到明天你女朋友给你答复,同意(resolved)或者拒绝(rejected),如果同意就准备结婚了,如果不同意就等下次再求婚,哈哈哈。
promise 是用来解决两个问题的:
这样构造 promise 实例,然后调用 .then.then.then 的编写代码方式,就是 promise。
let p = new Promise((resolve, reject) => { // 调用了Promise构造函数
// 做一些事情
// 然后在某些条件下resolve,或者reject
if (/* 条件随便写^_^ */) {
resolve()
} else {
reject()
}
})
p.then(() => { // 调用了promise实例的.then方法
// 如果p的状态被resolve了,就进入这里
}, () => {
// 如果p的状态被reject
})
new Promise((resolve, reject) => { // 这两个方法主要是用来修改状态的
console.log("开始求婚。")
console.log("。。。。。")
console.log("考虑一下。")
setTimeout(() => {
if (isHandsome || isRich) { // 当我们调用 resolve 函数的时候,Promise 的状态就变成 resolved
resolve('我同意!')
} else { // 当我们调用 reject 函数的时候,Promise 的状态就变成 reject
reject("拒绝:我们八字不合")
}
}, 2000)
})
// 如果一个 promise 已经被兑现(resolved)或被拒绝(rejected),那么我们也可以说它处于已敲定(settled)状
已成功 resolved 的回调和已失败 rejected 的回调
// 调用 Promise 对象的then方法,两个参数为函数
p.then(function(value){ // 成功
console.log(value);
}, function(season){ // 失败
console.log(season);
});
getNumber()
getNumber()
.then(function(data){
console.log('resolved');
console.log(data);
})
.catch(function(reason){
console.log('rejected');
console.log(reason);
});
catch() 的作用是捕获 Promise 的错误
其实它和 then 的第二个参数一样,用来指定 reject 的回调,用法是这样:
在执行 resolve 的回调(也就是上面 then 中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死 js,而是会进到这个 catch 方法中。请看下面的代码:
promise.then(
() => { console.log('this is success callback') }
).catch(
(err) => { console.log(err) }
)
效果和写在 then 的第二个参数里面一样。不过它还有另外一个作用:在执行 resolve 的回调(也就是上面 then 中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死 js ,而是会进到这个 catch 方法中。请看下面的代码:
getNumber()
.then(function(data){
console.log('resolved');
console.log(data);
console.log(somedata); //此处的somedata未定义
})
.catch(function(reason){
console.log('rejected');
console.log(reason);
});
有了 all,你就可以并行执行多个异步操作,并且在一个回调中处理所有的返回数据。
「谁跑的慢,以谁为准执行回调」
Promise 的 all 方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调
Promise
.all([runAsync1(), runAsync2(), runAsync3()])
.then(function(results){
console.log(results);
});
Promise.all 手撕代码题:
const myPromiseAll =(arr)=>{
let result = [];
return new Peomise ((resolve,reject)=>{
for (let i=0;i<arr.length;i++){
arr[i].then(data=>{
result[i] = data;
if(result.length === arr.length)//所有的都成功才执行成功的回调
{
resolve(result)
}//这里可以用计数器更好点
},reject)//有一个失败则执行失败的回调
}
})
}
//请求某个图片资源
function requestImg(){
var p = new Promise(function(resolve, reject){
var img = new Image();
img.onload = function(){
resolve(img);
}
img.src = 'xxxxxx';
});
return p;
}
//延时函数,用于给请求计时
function timeout(){
var p = new Promise(function(resolve, reject){
setTimeout(function(){
reject('图片请求超时');
}, 5000);
});
return p;
}
Promise
.race([requestImg(), timeout()])
.then(function(results){
console.log(results);
})
.catch(function(reason){
console.log(reason);
});
Promise.race()手撕代码用法:
function promiseRace(promises) {
if (!Array.isArray(promises)) {
throw new Error("promises must be an array")
}
return new Promise(function (resolve, reject) {
promises.forEach(p =>
Promise.resolve(p).then(data => {
resolve(data)
}, err => {
reject(err)
})
)
})
}
any() 方法还接受一组 promise 作为参数,并将它们打包到新的 promise 对象中。只要一个参数实例处于成功状态,新的 promise 就处于成功状态。参数实例均处于拒绝状态。新承诺处于拒绝状态。
Promise.any(promises).then(
(first) => {
// Any of the promises was fulfilled.
},(error) => {
// All of the promises were rejected.
}
);
注:同学们可以通过上面两道题目,举一反三,自己尝试写出手动实现 promise.any()
finally 方法用于指定无论 Promise 对象的最终状态如何,都将执行 finally。Finally 不接受参数。Finally 独立于先前的执行状态,不依赖于先前的运行结果。
const promise4 = new Promise((resolve, reject) => {
console.log(x + 1);});
promise4
.then(() => {
console.log("你好");}).catch((err) => {
console.log(err);}).finally(() => {
console.log("finally");});// finally
阅读量:2016
点赞量:0
收藏量:0