手写Pormise (三)

102 阅读1分钟

阶段三: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的结果,没有则不用回调
文章内容输出来源:拉勾教育Java高薪训练营;