一、Promise基础
1.为什么需要Promise?
js是一门单线程语言,所以早期我们在解决异步的场景时,通常使用回调函数来进行,但如果有多层异步函数嵌套的话(回调地狱),将非常不利于后续的维护。
为了能使回调函数以更优雅的方式进行调用,在ES6中产生了Promise的规范,它让异步操作变得近乎同步化。
2.Promise构造函数
- 该构造函数接受一个函数,此函数接受两个参数,分别为resolve和reject,代表我们需要改变当前实例的状态到已完成或已拒绝。
3.Promise的状态
Promise有三种状态:进行中/已完成/已拒绝
进行中的状态可以更改为已完成或已拒绝,已经更改过状态后无法继续更改,如:不能将已完成状态改为已拒绝状态。
4.then方法
- 可在上一个promise达到已完成时,继续执行下一个函数或Promise,同时通过resolve或reject时传入的参数,给下一个函数或promise传入初始值。
5.捕获拒绝状态
- 已拒绝的Promise,可以通过.catch方法或.then方法的第二个参数或try catch进行捕获。
二、Promise的方法
1.Promise.resolve(value):
返回一个Promise实例,并将它的状态设置为已完成,同时将它的结果作为传入onFulfilled函数的值。
2.Promise.reject(reason):
返回一个Promise实例,并将它的状态设置为已拒绝,同时将它的结果作为传入onRejected函数的原因。
3.Promise.race([promise1,promise2,...]):
返回一个Promise实例,接受一个含多个Promise实例的数组,当其中一个Promise实例状态改变时,就进入该状态不可改变。这里所有的Promise实例为竞争关系,只选择第一个进入改变状态的promise的值。
4.Promise.all([promise1,promise2,...]):
返回一个Promise实例,接受一个含多个Promise实例的数组,当所有Promise实例都成为已完成状态时,进入已完成状态,否则进入已拒绝状态。
5.Promise.allSettled():
返回一个Promise实例,在所有给定的Promise都已经fulfilled或rejected后返回对应状态,并带有一个对象数组,每个对象表示对应的Promise结果。
6.Promise.any():尚未被所有的浏览器完全支持
接收一个Promise可迭代对象,只要其中的一个 Promise 成功,就返回那个已经成功的 Promise 。如果可迭代对象中没有一个 promise 成功(即所有的 promises都失败/拒绝),就返回一个失败的 promise 和AggregateError类型的实例,它是 Error 的一个子类,用于把单一的错误集合在一起。本质上,这个方法和Promise.all()是相反的。
三、实现Promise.all()
Promise.myAll = (list => {
return new Promise((resolve, reject) => {
let count = 0
const values = []
list.forEach((item, i) => {
Promise.resolve(item).then(res => {
values[i] = res
count++
if (count === list.length) {
resolve(values)
}
}, err => {
reject(err)
})
});
})
})