本身动手实现一个 Promise

原生Promise关键特性

本身实现 Promise, 首先须要了解 原生 Promise 的一些 关键特性javascript

原生 Promise的关键特性 整理以下:java

  • 提供一个 构造函数 - Promise, 返回一个 promise 对象数组

    promise 对象 应包含 属性: 状态 - PromiseStatus(pending、resolved、rejected), 值 - PromiseValuepromise

    promise 对象初始状态pending, undefined缓存

  • 使用 构造函数 时须要传入一个 函数类型的参数 - fnfn 须要在 promise 对象构建完成之后当即执行bash

    fn 有两个 函数类型的参数 - resolvereject。当 fn 内部的异步操做完成 之后,调用 resolverejectpromise对象 的状态变为 终态(resolved / rejected)异步

    原生 Promise 中,resolverejectjavascript引擎 提供,不须要咱们提供。当咱们本身实现 promise 时,须要提供 resolvereject函数

    fn 在执行过程当中,若是 发生异常promise 对象 的状态会变为 rejectedui

  • resolve 用于将 promise实例对象的状态pending 置为 resolvedthis

    使用的时候,须要传入一个 参数,通常为 fn 内部异步操做返回的结果,会做为 promise 对象的值

    若是 没有传参数promise 对象 的值为 undefined

    若是传入的参数是一个 promise 对象,那么 传入的 promise 对象的状态会传递给当前 promise 对象, 具体状况以下:

    • 若是 传入的 promise 对象的状态为 pending,那么 当前 promise 对象的状态为 pending,等到 传入的 promise 对象的状态变为终态 后, 当前 promise 对象的状态才会变为相应的终态当前 promise 对象的值 会使用 传入的 promise 对象的值 更新。

    • 若是 传入的 promise 对象的状态为 resolved, 那么 当前 promise 对象的状态会变为 resolved值为传入的promise对象的值

    • 若是 传入的 promise 对象的状态为 rejected, 那么 当前 promise 对象的状态会变为 rejected值为传入的promise对象的值

  • reject 用于将 promise实例对象的状态pending 置为 rejected

    使用的时候,须要传入一个 参数,通常为 fn 内部异步操做返回的异常,会做为 promise 对象的值。参数也可为

    resolve 不一样,就算传入的参数为 promise 对象, 也 不会影响原 promise 对象的状态

  • promise对象的状态 一旦发生变化成为 终态, 就 不会再变化

  • 原型方法 - then,用于 注册promise 对象的状态 变为 终态(resolved/rejected) 时调用的 callback

    then 方法在使用的使用,须要传入两个 函数类型的参数- onFullfilledonRejected

    promise对象 的状态变为 resolved 时,执行 onFullfilled。 执行 onFullfilled 时, 会传入一个参数,该参数为 promise 对象的值

    promise对象 的状态变为 rejected 时,执行 onRejected。 执行 onRejected 时, 也会传入一个参数,该参数为 promise 对象的值

    onFullfilledonRejected 均可觉得

    then 方法会返回一个 新的 promise 对象, 初始状态为 pending

    新的 promise 对象的状态 变为 终态 时,可能遇到的状况以下:

    • onFullfilledonRejected 没有 正确注册

      没有正确注册,即 promise 对象 - p1 的状态 变为 resolved发现没有注册onFullfilled, 或者 promise 对象的状态 变为 rejected发现没有注册onRejected

      此时, p1.then() 返回的 promise对象-p2 的状态为 p1 的状态,p2 的值也为 p1 的值。

    • onFullfilledonRejected 正确注册新的 promise 对象 会根据 onFullfilled / onRjected返回值 修改状态以及更新值, 具体状况以下:

      • 若是 返回值普通值(普通对象、数值、字符串等)新的 promise 对象 的状态为 resolvedpromise对象的 值 更新为 返回值

      • 若是 没有返回值,默认为 return undefined新的 promise 对象 的状态为 resolvedpromise对象的 值 更新为 undefined

      • 若是返回一个 promise对象 - p2,那么 新的promise对象 - p1状态及值 会被影响。

        p2 的状态为 pendingp1 的状态为 pending,当 p2 的状态变为 终态 时,p1 的状态也变为 对应的终态值也更新

        p2 的状态为 resolvedp1 的状态也为 resolved,值为 p2 的值。

        p2 的状态为 rejectedp1 的状态也为 rejected,值为 p2 的值。

  • 原型方法 - catch,用于 注册promise 对象的状态 变为 rejected 时调用的 callback

    catch 方法在使用的时候,须要传入一个 函数类型的参数- onRejected

    promise对象 的状态变为 rejected 时,执行 onRejected。 执行 onRejected 时, 会传入一个参数,该参数为 promise 对象的值

    catch 方法会返回一个 新的 promise 对象, 初始状态为 pending,变为 终态 的状况和 then 方法一致。

  • 原型方法 - finally,用于 注册promise 对象的状态 变为 终态(resolved/rejected) 时调用的 callback

    finally 方法在使用的使用,须要传入一个 函数类型的参数- callback

    promise 对象 的状态变为 终态(resolved/rejected) 时,执行 callbackcallback 的参数为 , 即 callback 内部的操做不依赖 promise 对象 的值。

    finally 方法会返回一个 promise对象, 初始状态为 pending,变为 终态 的状况参照 then

    thencatch 方法中,若是 onFullfilled / onRejected 的返回值 不是 promise 对象, 那么 返回值 会做为 新的 promise 对象的值finally 方法会有稍许不一样,若是 callback的返回值 不是 promise 对象, 那么 新的 promise 对象的值原 promise 对象的值

  • 静态方法 - Promise.resolve, 用于 快速构建 一个 promise 对象

    使用 resolve 的时候,会传入 一个参数。参数的不一样, 会影响 返回的 promise 对象的状态和值,以下:

    • 参数为一个 promise 对象,不作任何处理, 直接返回传入的 promise 对象

    • 参数为 thenable 对象,即具备 then 方法 的对象, 返回一个 新的 promise 对象, 状态为 resolved, 值为 then方法的返回值

    • 参数为 普通值, 即 非promise对象非thenable对象, 返回一个 新的 promise 对象, 状态为 resolved, 值为 传入的参数

    • 参数为 , 返回一个 新的 promise 对象, 状态为 resolved, 值为 undefined

  • 静态方法 - Promise.reject,用于 快速构建 一个状态为 rejectedpromise 对象

    Promise.resolve 方法不一样, 无论传入的参数是什么值, 返回的的 promise 对象 的状态为 rejected, 值为 传入的参数

  • 静态方法 - Promise.all用于跟踪多个 promise 对象的状态变化

    all 方法使用时需传入 一个数组类型的参数, 数组中中包含若干个 promise 对象, 返回一个 promise 对象 - p1,状态为 pending

    当参数中 全部的 promise 对象的状态 变为 resolved 时, p1的状态 才会变为 resolved,此时 p1的值 是一个 数组数组元素参数数组中各个 promise 对象的值

    参数中 只要有一个 promise 对象的状态变为 rejectedp1的状态 就会变为 rejectedp1的值第一个状态为 rejected 的 promise 对象的值

  • 静态方法 - Promise.race用于跟踪多个 promise 对象的状态变化

    race 方法使用时需传入 一个数组类型的参数, 数组中中包含若干个 promise 对象, 返回一个 promise 对象 - p1,状态为 pending

    参数中 只要有一个 promise 对象的状态变为 终态p1的状态 就会变为 相应的状态p1的值第一个状态为 终态 的 promise 对象的值

  • 静态方法 - Promise.any用于跟踪多个 promise 对象的状态变化

    any 方法使用时需传入 一个数组类型的参数, 数组中中包含若干个 promise 对象, 返回一个 promise 对象 - p1,状态为 pending

    当参数中 全部的 promise 对象的状态 变为 rejected 时, p1的状态 才会变为 rejected,此时 p1的值 是一个 数组数组元素参数数组中各个 promise 对象的值

    参数中 只要有一个 promise 对象的状态变为 resolvedp1的状态 就会变为 resolvedp1的值第一个状态为 resolved 的 promise 对象的值

  • 静态方法 - Promise.allSetted用于跟踪多个 promise 对象的状态变化

    allSettled 方法使用时需传入 一个数组类型的参数, 数组中中包含若干个 promise 对象, 返回一个 promise 对象 - p1,状态为 pending

    当参数中 全部的 promise 对象的状态变为 终态p1的状态 就会变为 resolved, 此时 p1的值 是一个 数组数组元素参数数组中各个 promise 对象的值

  • 微任务队列

    在一个 事件循环 中,当 promise 对象的状态 变为 终态时, 会开启一个 微任务队列, 将 对应的callback 添加到 队列 中。 当 事件循环 中的 同步代码 执行完成之后,开始处理 微任务队列 中的 任务

    微任务队列 开始工做之后, 若是有 新的 promise 对象的状态变为终态, 会将 对应的callback 继续添加到 微任务队列 中等待处理。

    微任务队列 中的 全部任务处理完毕 之后就会被 清空,而后关闭微任务队列,直到下一次事件循环中有 promise 对象的状态变为终态时从新开启

实现 promise

根据上述 原生promise关键特性,咱们可本身动手逐步实现 Promise。实现过程以下:

  1. 模拟微任务队列

    在这里, 咱们使用 setTimeout一个数组 - queue 来模拟 微任务队列,以下:

    let queue = [] // 任务队列
    let flushing = false // 任务队列未启用
    let index = 0
    // 将任务添加到任务队列中
    // 若是是首次将任务添加到任务队列中,启动任务队列,
    //      并经过setTimeout实现同步代码执行完成之后处理任务队列中的任务
    // 若是添加任务时, 任务队列已启动, 直接将任务添加到任务队列中,等待处理
    function queueTask(task) {
        if (!queue.length) {
            // 启动任务队列
            flushing = true
            // 等同步代码执行完成之后, 处理任务队列中的任务
            setTimeout(flushQueue, 0)
        }
        // 将任务添加到任务列中
        queue.push(task)
    }
    // 处理任务队列中的任务
    function flushQueue() {
        // 遍历任务队列中的任务,处理每个任务
        while(index < queue.length) {
            queue[index].call()
            index++
        }
        // 处理完成之后,清空并关闭任务队列
        queue = []
        index = 0
        flushing = false
    }
    
    复制代码
  2. 构建 Promise 类

    要实现 Promise,首先须要提供一个 Promise 类。一个 Promise 类 须要 构造函数原型方法then、catch、finally静态方法resolve、reject、all、race、any、allSetted

    其次,咱们还须要一些 辅助函数exectorresolverejecthandle。其中, resolvereject 用于修改 promise 对象状态exector 用于 执行构造 promise 对象时传入的 fnhandle 用于处理 thencatchfinally 方法注册的 callback

    class MyPromise {
        // 构造函数
        constructor(fn) {}
        // 原型方法 - then
        then(onFullfilled, onRejected) {}
        // 原型方法 - catch
        catch(onRejected) {}
        // 原型方法 - finally
        finally(callback) {}
        // 静态方法 - resolve
        static resolve(value) {}
        // 静态方法 - reject
        static reject(reason) {}
        // 静态方法 - all
        static all(arr) {}
        // 静态方法 - race
        static race(arr) {}
        // 静态方法 - any
        static any(arr) {}
        // 静态方法 - allSetted
        static allSetted(arr) {}
    }
    // 辅助函数,用于执行构建 promise 对象传入的 fn
    function exector(fn) {}
    // 辅助函数,将 promise 对象的状态变为resolved
    function resolve(promise, value) {}
    // 辅助函数,将 promise 对象的状态变为rejectd
    function reject(promise, value) {}
    // 辅助函数,用于处理 promise 对象 的 callback
    function handle(promise, handler)
    复制代码
  3. 实现构造函数

    接下来,咱们首先来实现 构造函数 - constructor

    class MyPromise  {
        constructor(fn) {
            // promise 对象的初始状态为 'pending'
            this._status = 'pending'
            // promise 对象的初始值为 'undefined'
            this._value = undefined
            // 用于缓存注册的callback,当状态发生变动时,会遍历并处理
            this._handlers = []
            this._effects = []
            // then方法中会调用构造函数构建一个新的promise对象
            // 使用构造函数的时候,不传入fn,也就不会执行fn
            if(!fn) return
            // 执行 fn
            exector(this, fn)
        }
    }
    
    复制代码

    在构建 promise 对象 的时候,咱们会为 promise 对象 添加以下属性:_status_value_handlers_effects

    _statuspromise 对象状态,初始值为 'pending', 终态为 'resolved''rejected'

    _valuepromise 对象 的值,初始值为 undefined

    _handlers 用于缓存 promise 对象 经过 thencatchfinally 注册的 callback。等 promise 对象状态 发生变化时,遍历 _handlers 中的 callback 并处理。

    _effects 中存储的是 promise 对象。当咱们使用 resolve 方法修改 状态 时,若是传入的是一个 promise对象 - p1,那么 p1 的状态 会影响 原 promise 对象 - p2 的状态。此时咱们会把 p2 添加到 p1_effects 中, 等到 p1 的状态 发生变动时, 通知 p2 更新。

  4. 辅助函数 exector、resolve、reject、handle

    使用构造函数建立 promise 对象 时, 若是传入了 fn, 须要经过辅助函数 exector 来执行 fnexector 的过程以下:

    function exector(promise, fn) {
        try {
            // 执行fn, 传入 resolve 和 reject
            fn(value => {resolve(promise, value)},   // resolve
                reason => { reject(promise, reason)}) // reject
        } catch(e) {
            // 执行fn的过程当中,若是发生异常, 将promise对象的状态置为rejected
            reject(promise, e)
        }
    }
    复制代码

    执行fn的时候, 咱们传入 通过包装的函数 做为 resolvereject。当咱们拿到异步操做的结果后,将结果做为参数传入 resolvereject,将 promise 对象 的状态变为 resolvedrejected

    经过辅助函数 resolve, 咱们能够将 promise对象 的状态置为 resolved

    function resolve(promise, value) {
        // 若是 promise对象的状态已经为终态, 直接返回
        if (promise._status !== 'pending') return
        if (value && typeof value === 'object') {
            // 使用resolve时,若是传入的是一个promise对象,promise对象的状态会传递给当前promise对象
            if (value instanceof MyPromise) {
                // 传递状态
                promise._status = value._state
                // 传递值
                promise._value = value._value
                if (value._status !== 'pending') {
                    // 若是传入的promise对象的状态是resolved, 那么当前promise对象的状态会变为resolved
                    // 此时须要将当前promise对象注册的callback所有添加到微任务队列中
                    promise._handlers.forEach(handler => {
                        handle(promise, handler)
                    })
                } else {
                    // 若是传入的promise对象的状态是 pending
                    // 须要将当前promise对象添加到传入的promise对象的_effects列表中
                    // 等到传入的promise对象的状态发生变化时,通知当前promise对象进行状态变化
                    value._effects.push(promise)
                }
                return
            } else if (value.then && typeof value.then === 'function') {
                // 若是传入的是一个 thenable 对象
                exector(promise, value.then.bind(value))
                return 
            }
        }
        // 若是传入的是普通值, 那么将当前promise对象的状态置为resolved
        promise._status = 'resolved'
        // 传入的值为promise对象的值
        promise._value = value
        // 遍历_handlers列表, then、catch、finally注册的callback添加到微任务队列中
        promise._handlers.forEach(handler => {
            handle(promise, handler)
        })
        // 通知_effects列表中的promise对象进行状态变动
        promise._effects.forEach(item => {
            resolve(item, promise._value)
        })
    }
    复制代码

    经过辅助函数 reject, 咱们能够将 promise 对象 的状态变为 rejected

    function reject(promise, error) {
        // 若是promise对象的状态为终态, 直接返回
        if (promise._status !== 'pending') return
        // promise 对象 的状态变为 rejected
        promise._status = 'rejected'  
        // 传入的值为promise对象的值
        promise._value = error
        // 遍历_handlers列表, then、catch、finally注册的callback添加到微任务队列中
        promise._handlers.forEach(handler => {
            handle(promise, handler)
        })
        // 通知_effects列表中的promise对象进行状态变动
        promise._effects.forEach(item => {
            reject(item, promise._value)
        })
    }
    复制代码

    经过辅助函数 handle, 咱们能够将 promise对象 注册的 callback 收集到 _handlers 列表 中。当 promise 对象 的状态为 终态 时, 将注册的 callback 添加到 微任务队列 中。

    // handler是一个对象,里面包含promise对象注册的onFullfilled、onRejected 和 执行 'then''catch''finally'方法时返回的 promise对象
    function handle(promise, handler) {
        // 若是 promise 实例的状态为pending, 将注册的callback先收集起来。
        // 等promise对象的状态变为终态时,将callback添加到微任务队列中
        if (promise._status === 'pending') {
            promise._handlers.push(handler)
            return
        }
        // promise实例的状态为resolved或者rejected时, 将注册的callback添加到微任务队列中, 等待执行
        queueTask(function() {
            // 微任务队列启动后, 开始处理微任务队列中的任务
            // 若是promise 对象的状态为resolved, 获取onFullfilled
            // 若是promise 对象的状态为rejected, 获取onRejected
            let cb = promise._status === 'resolved' ? handler.onFullfilled : handler.onRejected;
            if (!cb) {
                // 若是callback没有正确注册
                // 'p2 = p1.then(onFullfilled, onRejected)'
                // 若是p1没有正确注册callback,即p1为resolved,却没有注册onFullfilled;
                // 或者 p1为rejected,却没有注册onRejected
                if (promise.status === 'resolved') {
                    // 若是p1的状态为resolved,将p2的状态置为resolved
                    // p2的值为p1的值
                    resolve(handler.promise, promise._value)
                } else {
                    // 若是p1的状态为rejected,将p2的状态置为rejected
                    // p2的值为p1的值
                    reject(handler.promise, promise._value)
                }
                return
            }
            // 若是callback有正确注册
            try {
                // 执行callback
                let res = cb(promise._value)
                // 'p2 = p1.then()'
                // 将p2的状态置为resolved, 并使用callback的返回值做为p2的值
                resolve(handler.promise, res)
            } catch (e) {
                // callback执行异常,将p2的状态置为rejected,将异常做为p2的返回值
                reject(handler.promise, e)
            }
        })
    }
    复制代码
  5. then

    promise对象 构建完成之后, 咱们须要经过 then 方法来注册 onFullfilledonRejected。等到 promise 对象 的状态变为终态时,执行对应的 callback

    class Promise {
        then(onFullfilled, onRejected) {
            let P = this.constructor
            // promise.then 方法会返回一个 promise 实例
            let res = new P()
            // 若是当前promise对象的状态为pending,会将{onFullfilled, onRejected,..} 添加到_handlers中,等到状态变为终态, 再作处理
            // 若是当前promise对象的状态为终态, 会将callback添加到微任务队列中
            handle(this, {
                onFullfilled,
                onRejected,
                promise: res
            })
            // 返回一个新的promise对象
            return res
        }
    }
    复制代码
  6. catch

    catch 方法用于注册当 promise 对象的状态 变为 rejected 时调用的 callback

    catch(onRejected) {
        this.then(null, onRejected)
    }
    复制代码
  7. finally

    finally,用于 注册promise 对象的状态 变为 终态(resolved/rejected) 时调用的 callback

    // 只要promise实例的状态发生变化, 都会执行,返回一个promise实例
    // promise实例的值为上一个promise实例的值
    finally(callback) {
        let P = this.constructor
        let res = new P()
        handle(this, {
            onFullfilled: () => {
                // 当原promise实例的状态变为resolved时,执行callback
                callback()
                // 返回原promise对象的值做为新promise对象的值
                return this._value
            },
            onRejected: () => {
                // 当原promise实例的装填变为rejected, 执行callback
                callback()
                // 返回原promise对象的值做为新promise对象的值
                return this._value
            },
            promise: res
        })
        // 返回一个新的promise对象
        return res
    
    }
    复制代码
  8. Promise.resolve

    静态方法 resolve, 用于快速构建一个 promise对象promise 对象的状态 有传入的参数决定。

    static resolve(value)  {
        // 传入一个promise对象, 直接返回参数
        if (value instanceof MyPromise) return value
        // 传入一个thenable对象,构建一个新的promise对象
        // thenable对象的状态和值决定新的promise对象的状态和值
        if (value && value.then && typeof value.then === 'function') {
            return new MyPromise(value.then.bind(value))
        }
        // 其余类型的参数,直接返回状态为resolved的promise对象
        // promise对象的值为传入的参数
        let promise = new MyPromise()
        promise._status = 'resolved'
        promise._value = value
        return promise
    }
    复制代码
  9. Promise.reject

    静态方法 reject,用于快速构建一个状态为 rejectedpromise对象,传入的参数为 promise 对象 的值。

    static reject(value) {
        let promise = new MyPromise()
        promise._state = 'rejected'
        promise._value = value
        return promise
    }
    复制代码
  10. Promise.all

    静态方法 all 会返回一个 新的 promise 对象。当 传入的全部 promise 对象 的状态都为 resolved, 返回的 新的 promise 对象 的状态变为 resolved, 不然为 rejected

    static all(arr) {
        var args = Array.prototype.slice.call(arr)
        // all 方法会返回一个新的promise对象
        return new MyPromise(function(resolve, reject) {
            if (args.length === 0) return resolve([])
            let remain = args.length
            // 若是promise对象的状态为resolved, 把promise对象的值先缓存起来
            // 若是promise对象的状态为pending,等promise的状态变为resolved,把promise对象的状态缓存起来
            // 当全部的promise对象的状态为resolved时,将新的promise对象的状态置为resolved, 使用缓存的数组做为新的promise对象的值
            // 若是promise对象的状态为rejected,直接将新的promise对象的状态置为rejected
            function func(index, val) {
                if (typeof val === 'object') {
                    if (val instanceof MyPromise) {
                        // promise对象的状态为resolved, 缓存promise对象的值
                        if (val._status === 'resolved') return func(index, val._value)
                        // promise对象的状态为rejected,新的promise对象的状态为rejected
                        if (val._status === 'rejected') {
                            // 新的promise对象的值为第一个状态为rejected的promise对象的值
                            reject(val._value)
                            return false
                        }
                        // promise对象的状态为pending
                        val.then(value => {
                            func(index, value)
                        }, reject)
                        return true
                    } else if (val.then && typeof val.then === 'function') {
                        // 传入的参数是thenable对象
                        let p = new MyPromise(val.then.bind(val))
                        p.then(value => {
                            func(index, value)
                        }, reject)
                        return true
                    }
                }
                // 若是promise对象的状态为resolved, 缓存promise对象的值
                args[index] = val
                // 传入的promise对象的状态都变为resolved, 返回的promise对象的状态变为resolved
                // 值为一个数组,包含全部promise对象值
                if (--remain === 0) {
                    resolve(args)
                }
                return true
            }
            // 遍历传入的promise对象
            for(let i = 0; i < args.length; i++) {
                if (!func(i, args[i])) return false
            }
        })
    }
    复制代码
  11. Promise.race

    静态方法 race 会返回一个 新的 promise 对象。当 传入的全部 promise 对象 的状态只要有一个是 终态 时, 返回的 新的 promise 对象 的状态变为 相应的状态

    static race(arr) {
        // 返回一个promise对象
        return new MyPromise(function(resolve, reject) {
            arr.forEach(function(value){
                //  arr 中只要有一个 promise 实例的状态为发生变化, 返回的 promise的状态就会发生变化
                // 返回的promise对象的值为参数中第一个状态变化的promise对象的值
                MyPromise.resolve(value).then(resolve, reject);
            });
        })
    }
    复制代码
  12. Promise.allSettled

    静态方法 allSettled 会返回一个 新的 promise 对象。当 传入的全部 promise 对象 的状态都变为 终态 时, 返回的 新的 promise 对象 的状态变为 resolved

    static allSettled(arr) {
        var args = Array.prototype.slice.call(arr)
        // 返回一个新的promise对象
        return new MyPromise(function(resolve, reject) {
            if (args.length === 0) return resolve([])
            let remain = args.length
            function func(index, val) {
                if (typeof val === 'object') {
                    // 参数为promise对象
                    if (val instanceof MyPromise) {
                        // promise对象的状态为resolved, 缓存promise对象的值
                        if (val._status === 'resolved') return func(index, val._value)
                        // promise对象的状态为rejected, 缓存promise对象的值
                        if (val._status === 'rejected') return func(index, val._value)
                        // promise对象的状态为pending, 等promise对象的状态变为终态时,缓存promise对象的值
                        val.then((value) => {
                            func(index, value)
                        }, (error) => {
                            func(index, error)
                        })
                    } else if (val.then && typeof val.then === 'function') {
                        // 参数为thenable对象
                        let p = new MyPromise(val.then.bind(val))
                        p.then((value) => {
                            func(index, value)
                        }, (error) => {
                            func(index, error)
                        })
                    }
                }
                // 参数为普通值,直接缓存
                args[index] = val
                if (--remain === 0) {
                    // 全部的promise对象的状态都为终态,将返回的promise对象的状态变为resolved
                    // 值为全部promise对象的值
                    resolve(args)
                }
            }
            // 遍历传入的全部promise对象
            for(let i = 0; i < args.length; i++) {
                func(i, args[i])
            }
        })
    }
    复制代码
  13. Promise.any

    静态方法 any 会返回一个 新的 promise 对象。当 传入的全部 promise 对象 的只要有一个状态为 resolved, 返回的 新的 promise 对象 的状态变为 resolved。 只有 全部 promise 对象 的状态都为 rejected, 返回的 新的 promise 对象 的状态才为 rejected

    static any(arr) {
        var args = Array.prototype.slice.call(arr)
        // 返回一个新的promise对象
        return new MyPromise(function(resolve, reject) {
            if (args.length === 0) return resolve([])
            let remain = args.length
            function func(index, val) {
                if (typeof val === 'object') {
                    // 传入的参数为promise对象
                    if (val instanceof MyPromise) {
                        // promise对象的状态为resoved, 则返回的promise对象的状态为resolved
                        // 值为第一个状态为resolved的promise对象的值
                        if (val._status === 'resolved') {
                            resolve(val._value)
                            return false
                        }
                        // promise对象的状态为rejected, 缓存promise对象的值
                        if (val._status === 'rejected') return func(index, val._value)
                        // promise对象的状态为pending, 等promise对象的状态变为rejected是,缓存promise对象的值;
                        // 变为resolved时, 返回的promise对象的状态变为resolved
                        val.then(resolve, (error) => {
                            func(index, error)
                        })
                        return true
                    } else if (val.then && typeof val.then === 'function') {
                        // 传入的参数是thenable对象
                        let p = new MyPromise(val.then.bind(val))
                        p.then(resolve, (error) => {
                            func(index, error)
                        })
                        return true
                    }
                }
                // 传入的参数是普通值
                args[index] = val
                // 全部的promise对象的状态都为rejected
                if (--remain === 0) {
                    // 将返回的promise对象的状态变为rejected
                    // 返回的promise对象的值为传入的全部promise对象的值
                    reject(args)
                }
                return true
            }
            // 遍历传入的promise对象
            for(let i = 0; i < args.length; i++) {
                if (!func(i, args[i])) return false
            }
        })
    } 
    复制代码
相关文章
相关标签/搜索