一、Promise的作用
Promise是用来解决异步编程问题,使用同步操作的形式表达异步操作的流程,解决了传统异步操作中回调层层嵌套的问题。
二、Promise的状态
- promise包含三种状态:pending(进行中)、fulfilled(成功)、rejected(失败)。
- 状态改变只有两种可能:
- pending->fulfilled
- pending->rejected
- 状态一旦改变,就不会再变。
三、Promise的基本使用
- Promise接收一个回调函数,该回调函数接受两个参数,resolve和reject。
- resolve和reject两个函数是Promise内部实现的。
- resolve中将pending状态变为fulfilled状态,在异步操作成功时调用,将异步操作的结果作为参数传递出去。
- reject中将pending状态变为rejected状态,在异步操作失败时调用,将异步操作的报错作为参数传递出去。
- Promise实例生成后,可用then方法来指定resolve和reject的回调函数。
let promise = new Promise(function(resolve, reject) {
let a = 1;
if(a==1) {
resolve(1);
} else {
reject(2);
}
}).then(function(val) {
console.log(val);
},function(err) {
console.log(err);
});
四、Promise的执行顺序
Promise的执行顺序:
- Promise在新建时会立即执行;
- 执行所有同步任务执行;
- 执行then方法指定的回调函数。 例子:
let promise = new Promise(function(resolve, reject) {
let a = 1;
if(a==1) {
resolve(1);
} else {
reject(2);
}
console.log(1);
}).then(function(val) {
console.log(2);
},function(err) {
console.log(err);
});
console.log(3);
// 1
// 3
// 2
五、异步操作的结果是返回另一个异步操作
当异步操作p2的resolve的参数为另一个异步操作p1时,p2会等待p1返回结果,p1的状态决定p2的状态。 例子:
let p1 = new Promise(function(resolve, reject) {
reject(new Error('fail'));
})
let p2 = new Promise(function(resolve, reject) {
resolve(p1);
})
console.log(p2);
执行结果:
六、Promise.prototype.then()
then(resovleCallback, rejectCallback):指定resolve和reject的回调函数,返回一个新的Promise实例。
例子:
let p = new Promise(function(resolve, reject) {
resolve(1);
}).then(function(val) {
console.log(val)catch
return 2;
}).then(function(val) {
console.log(val)
return 3;
})
console.log(p);
执行结果:
七、Promise.prototype.catch()
catch(rejectCallback):指定发生错误时的回调函数,可以捕获到前面如何一个Promise实例发生的错误。
例子:
let p = new Promise(function(resolve, reject) {
reject(new Error('失败'))
}).then(function(val) {
console.log(val)
}).catch(function(err) {
console.log(err);
})
执行结果:
注意:如果没有使用catch方法,浏览器会报错,但是不会退出进程、终止脚本执行,即后面的代码仍然正常执行。
例子:
let p = new Promise(function(resolve, reject) {
reject(new Error('失败'))
}).then(function(val) {
console.log(val)
})
setTimeout(function() {
console.log(1)
}, 1000);
执行结果:
八、Promise.prototype.finally()
finally():无论promise最后的状态如何,都会执行finally方法指定的回调函数。 例子:
let p = new Promise(function(resolve, reject) {
resolve(1)
}).then(function(val) {
console.log(val)
}).finally(function() {
console.log(123)
})
执行结果:
九、Promise.resolve()
1.参数
- 若接收的参数为Promise实例,则返回该实例;
- 若接收的参数不为Promise实例,则转化为Promise实例,如果该参数原本带有then方法,则转化后立即执行then方法。 2.返回一个新的Promise实例。
例子:
const obj = {
then: function(resolve, reject) {
resolve(111);
}
}
const p = Promise.resolve(obj);
console.log(p);
执行结果:
十、Promise.reject()
- 返回一个新的状态为rejected的Promise实例。
- 参数将作为后续方法的参数。
例子:
const p = Promise.reject('失败');
p.catch(function(err) {
console.log(err);
})
console.log(p);
执行结果:
十一、Promise.all()
all(arr): 接收一个数组或其他具有Iterator 接口的数据,当数组中的元素不为Promise实例时,自动调用Promise.resolve()将其转化为Promise实例。 例子:
const p = Promise.all([p1, p2, p3]);
- p的状态由p1,p2,p3决定:
- 当p1,p2,p3的状态都为fulfilled时,p才为fulfilled, p1,p2,p3的返回值组成数组传递给p的回调函数。
- 当p1,p2,p3中有一个状态为rejected时,p为rejected,第一个rejected的返回值传递给p的回调函数。
2.catch的使用:
- 当p1,p2,p3中没有设置catch方法时,若出现错误,会使用p中的catch方法。
- 若设置了catch方法,则若出现错误,会被他们自身的catch捕获,执行完成后,返回一个新的Promise实例给到p的回调函数,所以p的catch并不会被触发,p的状态为fulfilled。 例子:
const p1 = new Promise(function(resolve, reject) {
resolve(1);
})
const p2 = new Promise(function(resolve, reject) {
reject(new Error('失败'));
}).catch(function(err) {
console.log(err);
});
const p = Promise.all([p1,p2]).catch(function(err) {
console.log(err);
});
console.log(p);
执行结果:
十二、Promise.race()
race(array):接收参数与all(array)一样,接收一个数组或其他具有Iterator 接口的数据,当数组中的元素不为Promise实例时,自动调用Promise.resolve()将其转化为Promise实例。
例子:
const p = Promise.race([p1, p2, p3]);
1.p的状态: p1,p2,p3哪个先更改状态时,p就随之更改状态,先更改状态的实例的返回值传递给p的回调函数。 例子:
const p1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(1);
}, 200)
})
const p2 = new Promise(function(resolve, reject) {
setTimeout(function() {
reject(new Error('失败'))
}, 100)
})
const p = Promise.race([p1,p2]);
p.then(function(val) {
console.log(val)
}).catch(function(err) {
console.log(err);
});
console.log(p);
执行结果:
十三、Promise.allSettled()
allSettled():接收参数与all(array)一样,接收一个数组或其他具有Iterator 接口的数据,当数组中的元素不为Promise实例时,自动调用Promise.resolve()将其转化为Promise实例。
例子:
const p = Promise.allSettled([p1, p2, p3]);
1.p的状态: 当p1,p2,p3都返回结果时,无论返回的状态是fulfilled还是reject,p的状态都为fulfilled,不会变成rejected。 p的回调函数接收到的是参数实例返回的状态组成的数组。
- 当参数实例返回的状态是fulfilled时,传递的返回值是
{status:'fulfilled', value:resolve值} - 当参数实例返回的状态是fulfilled时,传递的返回值是
{status:'rejected', reason:失败原因}
例子:
const p1 = new Promise(function(resolve, reject) {
resolve(1);
})
const p2 = new Promise(function(resolve, reject) {
reject(new Error('失败'))
})
const p = Promise.allSettled([p1,p2]);
console.log(p);
执行结果:
十四、Promise.any()
any():接收参数与all(array)一样,接收一个数组或其他具有Iterator 接口的数据,当数组中的元素不为Promise实例时,自动调用Promise.resolve()将其转化为Promise实例。 例子:
const p = Promise.any([p1, p2, p3]);
1.p的状态:
- 当p1,p2,p3有一个返回fulfilled状态时,p的状态就为fulfilled,该参数实例的返回值传给p的回调函数;
- 当p1,p2,p3的状态都为rejected时,p的状态才为rejected,所有报错的返回值组成数组传递给p的回调函数。 例子:
const p1 = new Promise(function(resolve, reject) {
reject(new Error('失败1'))
})
const p2 = new Promise(function(resolve, reject) {
reject(new Error('失败'))
})
const p = Promise.any([p1,p2]);
console.log(p);
执行结果: