手写了一个promise,Promise.all 方法传进去实例的onFulfilled 为什么没有运行?

1.传递给all方法的实例我已经调用resolve方法
2.Promise.all 中的 Promise.resolve(iterator).then()的这个then方法可有可无, 因为只需要拿到传入实例的结果即可这里不对数据进行二次处理比如return data + 'a'

var errObj
    function Promise(executor) {
        this.promiseResult = "";
        this.errorInfo = "";

        this.state = "pending"

        this.onFulfilled = value => value;
        this.onRejected = error => {
            throw error
        }

        try {
            executor(this.resolve.bind(this), this.reject.bind(this))
        } catch (error) {
            this.reject(error)
            errObj = this
            alert(error)
        }
    }

    Promise.prototype.resolve = function (data) {
        if (this.state === "pending") {
            this.promiseResult = data
            this.state = "fulfilled"
        }
    }

    Promise.prototype.reject = function (err) {
        if (this.state === "pending") {
            this.errorInfo = err
            this.state = "rejected"
        }
    }

    Promise.prototype.then = function (onFulfilled, onRejected) {

        this.onFulfilled = typeof onFulfilled === "function" ? onFulfilled : this.onFulfilled;
        this.onRejected = typeof onRejected === "function" ? onRejected : this.onRejected;

        var self_ = this;


        var pro = new Promise(function (resolve, reject) {

            Object.defineProperty(self_, "state", {
                configurable: true,
                get() {
                    return this._state || "pending"
                },
                set(val) {
                    alert(123)
                    this._state = val
                    if (val === "fulfilled") {
                        setTimeout(function(){
                            resolve(self_.onFulfilled(self_.promiseResult))
                        })
                    } else {
                        setTimeout(function(){
                            self_.onRejected(self_.errorInfo)
                        })
                    }
                }
            })
        })

        return pro
    }

    Promise.prototype.catch = function (onReject) {
        return this.then(null, onReject)
    }

    Promise.prototype.finally = function (callback) {
        return this.then(
            function () {
                callback()
            },
            function () {
                callback()
            }
        )
    }

    Promise.resolve = function (value) {
        if (value instanceof Promise) {
            return value
        }

        return new Promise(function (resolve, reject) {
            if (value && value.then && typeof value.then === "function") {

                value.then(resolve, reject)
            } else {
                resolve(value)
            }
        })
    }

    Promise.reject = function (error) {
        return new Promise(function (resolve, reject) {
            reject(error)
        })
    }

    Promise.all = function (array) {
        // debugger
        var result = []
        return new Promise(function (resolve, reject) {
            // debugger
            if (typeof Object.getPrototypeOf(array)[Symbol.iterator] !== "function" ) {
                throw new Error('传入的数据没有部署迭代器')
            }

            if(array.length === 0){
                resolve(result)
            }

            else{

                for (const iterator of array) {
                    Promise.resolve(iterator).then(
                        function(data){
                            result.push(data)
                            if(result.length === array.length){
                                resolve(result)
                            }
                        },
                        function(error){
                            reject(error)
                        }
                    )
                }
            }
        })
    }

var p = new Promise(function (resolve, reject) {
resolve(123)
})

var p1 = new Promise(function (resolve, reject) {
resolve(1)
})

var p2 = new Promise(function (resolve, reject) {
resolve(123)
})

var ps = Promise.all([p, p1, p2])
阅读 2.5k
2 个回答

先回答问题

then方法实现有问题,没有考虑调用then时,Promise对象已经是fulfilled/rejected的场景。

其他问题:

不知道题主写代码前是否参考了Promise A+规范。反正这个实现问题很多。then方法实现比较复杂,建议对照下Promise A+规范或者看看其他第三方库。

顺便指出其他几个的问题:

  1. Promise.all实现方式不对,不能使用数组的push,因为使用push不能保证返回值数组的元素顺序要和入参Promise对象数组顺序一致。
  2. Promise.prototype.finally实现方式不对,看看这个文章promsie.finally(onFinally)不等价于 promsie.then(onFinally, onFinally)

你执行 Promise.all([p, p1, p2]).then()then 的时候

var pro = new Promise(function (resolve, reject) {}

里面又没有改state的值, set(val) 怎么会执行呢