阶段三:all、resolve、reject、finally、catch的实现
function p1 () {
return new Promise (function(resolve, reject) {
setTimeout(() => {
resolve('p1')
}, 2000)
})
}
function p2 () {
return new Promise (function(resolve, reject) {
resolve('p2')
})
}
Promise.all(['a', 'b', p1(), p2(), 'c']).then((res) => {
console.log(res);
});
// ["a", "b", "p1", "p2", "c"]
Promise.resolve(p1()).then((value) => {
console.log('123', value);
});
// 123 p1
p2().finally(() => {
console.log('finally');
return p1();
}).then((value) => {
console.log('finally', value);
}, reason => {
console.log('finally', reason);
})
// finally p2
通过Promise使用可以知道all、resolve、reject、finally、catch的基本功能,
all:
// 静态方法 all
static all (array) {
let result = [];
let index = 0;
return new MyPromise((resolve, reject) => {
function addData (key, value) {
result[key] = value;
if (++index === array.length) {
// 处理异步, array中如果有异步函数,
// 统一在此处判断长度,表示是否全部都执行完了
resolve(result);
}
}
for (let i = 0; i < array.length; i++) {
let current = array[i];
if (current instanceof MyPromise) {
// promise 对象
current.then((value) => {
addData(i, value);
}, reason => reject(reason))
} else {
// 普通值
addData(i, array[i]);
}
}
})
}
- return 一个promise对象,支持后续链式调用
- index标记,用于判断回调是否完成。之所以不在循环后直接回调,需要回调中考虑异步函数,使用index标记的方式来解决异步问题
- 数组中可能存在值、promise对象;需要判断,普通值则默认resolve,promise对象则根据实际情况,
- all方法,全部promise都resolve的时候 === resolve;有一个reject,直接reject
static resolve (value) {
if (value instanceof MyPromise) return value;
return new MyPromise(resolve => resolve(vlaue));
}
static reject (value) {
if (value instanceof MyPromise) return value;
return new MyPromise(resolve => reject(vlaue));
}
- resolve 、reject方法:就是直接将值传入下一个promise,供链式调用
// 成功与否都返回结果
// 支持then继续链式调用
finally (callback) {
return this.then((value) => {
return MyPromise.resolve(callback().then(() => value));
}, (reason) => {
return MyPromise.resolve(callback().then(() => {
throw reason;
}));
});
}
catch (failCallBack) {
return this.then(undefined, failCallBack);
}
- finally,就是手动链式调用多一次then,根据状态然后回调
- catch,也是手动调用一次then,但是只获取reject的结果,没有则不用回调