手写Promise,1.7promise中all(),race(),resolve(),cath(),finally()的实现

HeiYanjing -
手写Promise,1.7promise中all(),race(),resolve(),cath(),finally()的实现

Promise.all()
Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
Promise.all()方法接受一个数组作为参数,数组中如果有不是promise实例的情况,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。
Promise.all()返回值也是一个promise对象,当所有状态都变成fulfilled,返回值的状态才会变成fulfilled,当有一个promise实例的状态变成rejected,此时第一个被reject的实例的返回值,会传递给返回值的回调函数。

实现过程中定义一个执行结果的数组,遍历all()参数,如果是普通值,直接进入结果数组,如果是promise实例,就先执行,因为for循环有立即执行的特点,而我们的promise实例有可能会有异步代码,向下传递执行结果的时候必须要保证我们所有的实例执行完。传递结果之前要判断所有实例代码是否执行完。

    static all(array) {
        let result = [];
        // 用于判断当前执行值是否等于数组长度,相等时才执行resolve()
        let idx = 0;

        return new MyPromise((resolve, reject) => {
            // 添加元素方法
            function addElement(index, value) {
                result[index] = value;
                idx++;
                if (idx === array.length) {
                    resolve(result)
                }
            }
            for (let i = 0; i < array.length; ++i) {
                let cur = array[i];
                // 判断cur是否是普通值,普通值直接进入result数组,
                // promise对象就执行它,调用then方法,执行成功则添加到result数组,如果失败
                if (cur instanceof MyPromise) {
                    // promise对象
                    cur.then(value => addElement(i, value), reason => reject(reason))
                } else {
                    // 普通值
                    addElement(i, array[i]);
                }
            }
        })
    }

promise.race()
race()方法类似,更加简单,遍历传入参数(数组对象),如果是普通值就调用resolve()回调,如果是promise实例,执行then方法

    static race(array) {
        return new MyPromise((resolve, reject) => {
            for (let i = 0; i < array.length; ++i) {
                let cur = array[i];
                if (cur instanceof MyPromise) {
                    cur.then(resolve, reject);
                } else {
                    resolve(cur)
                }
            }
        })
    }

promise.resolve()
将现有对象转换为pomise对象,它的返回值就是一个promise对象。方便后面调用then方法。实现它只需要稍作判断即可

    static resolve(e) {
        if (e instanceof MyPromise) {
            return e;
        } else {
            return new MyPromise(resolve => resolve(e))
        }
    }

Promise.prototype.finally()
finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。finally方法的回调函数不接受任何参数,不依赖于 Promise 的执行结果。函数体内执行then方法会返回一个promise对象,成功回调或者失败回调执行callback即可,并且返回成功回调结果或者抛出失败异常,但是考虑到有异步代码的情况,借助resolve()方法,在resolve方法中把callback调用的结果传递出去,无论是普通值还是promise都转成promise对象。之后就可以执行then方法。

    finally(callback) {
        return this.then(value => {
            return MyPromise.resolve(callback()).then(() => value);
        }, reason => {
            return MyPromise.resolve(callback()).then(() => {
                throw reason
            })
        })
    }

Promise.prototype.catch()
Promise.prototype.catch()方法是.then(null, rejection).then(undefined, rejection)的别名,用于指定发生错误时的回调函数。then()方法指定的回调函数,如果运行中抛出错误,也会被catch()方法捕获。
Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。
跟传统的try/catch代码块不同的是,如果没有使用catch()方法指定错误处理的回调函数,Promise 对象抛出的错误不会传递到外层代码,即不会有任何反应。
在catch方法中执行then方法,第一次参数传入null或者undefined。第二个参数就是failCallback

    catch (failCallback) {
        this.then(undefined, failCallback)
    }
特别申明:本文内容来源网络,版权归原作者所有,如有侵权请立即与我们联系(cy198701067573@163.com),我们将及时处理。
上一篇: HTML学习笔记

Tags 标签

javascript前端node.jses6

扩展阅读

加个好友,技术交流

1628738909466805.jpg