Codog

关注微信公众号:Codog代码狗

0%

如何实现Promise

Promise.all

先看all的行为:

image

自己实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 非实例上的方法,所以直接在Promise上实现
Promise.myAll = function(list) {
return new Promise((resolve, reject) => {
const length = list.length;
let count = 0;
const res = [];
for (let i = 0; i < length; i++) {
Promise.resolve(list[i]).then(r => {
res[i] = r;
count++;
if (count === length) {
resolve(res)
}
}).catch(e => {
reject(e)
})
}
})
}

测试一下:

1
2
3
4
5
6
7
Promise.myAll([1, 2, Promise.reject('error')]).then(res => console.log(res)).catch(e => console.error('Get error: ', e))

Promise.myAll([1, 2, Promise.resolve('success')]).then(res => console.log(res)).catch(e => console.error('Get error: ', e))

// Output: 这里的顺序也是个问题。。为啥成功的在前面呢,success在前面也是成功的先返回
[1, 2, "success"]
Get error: error

Promise.race

p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

Promise A+规范

https://github.com/xieranmaya/Promise3/blob/master/Promise3.js
https://github.com/xieranmaya/blog/issues/3

最后

记住了之前理解有误的地方,一个promise是可以被多次使用,也可以分开执行:

1
2
3
4
5
6
7
8
9
10
11
// 比如某个promise需要一定的执行时间,可以放在开头让它提前执行,在后面需要的时候再引用,可以节省一定时间

let promise = new Promise(resolve => {
resolve(data)
})

// other code

promise.then(res => func1(res))

promise.then(res => func2(res))

then与catch对后续状态的改变

image