sue手撕系列-Promise

184 阅读12分钟

一、介绍

Promise是用来处理异步操作,使得异步代码可以和同步代码一样

1.用法

const promise = new Promise((resolve, reject) => {
  // 异步操作  
  setTimeout(() => { 
    resolve('成功的结果'); // 操作成功,调用resolve函数  
  }, 1000);  
});  
  
promise.then(result => {  
  console.log(result); // '成功的结果'  
}).catch(error => {  
  console.log(error); // 不会执行,因为Promise已经被解析  
});

2.特点

  1. promise有三种状态,分别是pending(进行中)、fulfilled(已成功)、rejected(已失败),
    • 状态一旦发生改变,就不能再变 (即 pending -> fulfilled 、 pending -> rejected)
  2. 接受一个函数作为参数,该函数的参数为 resolve 和 reject
    • resolve 作用:将Promise对象的状态从 pending => fulfilled
    • reject 作用:将Promise对象的状态从pending => reject

3.方法介绍

  • then() : 实例状态发生改变时的回调函数
  • catch() : 用于指定发生错误时的回调函数
  • finally() : 用于指定不管Promise对象最后状态如何,都会执行的操作
  • all() : 接收一个Promise数组,每个请求都成功才会返回成功结果数组,否则会报错
  • race() : 接收一个Promise数组,哪个最快返回,就返回哪个结果
  • allSettled() : 接收一个Promise数组,无论成功与否,返回集合数组
  • any():接收一个Promise数组,如果有一个成功,则返回成功,当所有都失败,则会报错

二、手写Promise基本功能

step1:

目的:初始化MyPromise

代码解析:

  1. 初始化参数
    • promise有三种状态,定义状态变量 promiseStatus
    • 最后返回的值,定义返回值变量 promiseResult
    • promise有 resolve、reject 方法,定义 resolve、reject 方法
  2. 初始化this绑定
    • resolve、reject绑定在实例上,谁调用指向谁
  3. 立即执行函数

代码编写:

class MyPromise{
    constructor(executor){
        this.initValue() // 1.初始化参数
        this.initBind() // 2. 初始化this绑定
        executor(this.resolve,this.reject) // 3.立即执行函数
    }
    initValue(){
        this.promiseStatus = 'pending' // 状态
        this.promiseResult = null // 返回的值
    }
    initBind(){
        this.resolve = this.resolve.bind(this) // 绑定在实例上
        this.reject = this.reject.bind(this)
    }
    // 定义 resolve、reject 方法
    resolve(res){}
    reject(err){}
}

测试一下:

new MyPromise((resolve, reject) => {
    console.log('hello Promise') // hello Promise
})

step2:

目的:resolve和reject回调,三种状态转换

代码解析:

  1. promise的状态一旦发生改变,就不能再变,所以当状态为 pending 才会执行
  2. 改变promise的状态
    • resolve 方法,把 promise 的状态从 pending -> fulfilled
    • reject 方法,把 promise 的状态从 pending -> rejected
  3. 改变返回的值
    • resolve 方法,promiseResult = res
    • reject 方法,promiseResult = err

代码编写:

class MyPromise{
    constructor(executor){
        this.initValue()
        this.initBind()
        executor(this.resolve,this.reject) 
    }
    initValue(){
        this.promiseStatus = 'pending' 
        this.promiseResult = null 
    }
    initBind(){
        this.resolve = this.resolve.bind(this)
        this.reject = this.reject.bind(this)
    }
    resolve(res){
        if(this.promiseStatus === 'pending'){  // 1.状态一旦发生改变,就不能再变
            this.promiseStatus = 'fulfilled' // 2. pending -> fulfilled
            this.promiseResult = res // 3.改变返回的值
        }
    }
    reject(err){
        if (this.promiseStatus === 'pending') { // 1.状态一旦发生改变,就不能再变
            this.promiseStatus = 'rejected'  // 2. pending -> rejected
            this.promiseResult = err  // 3.改变返回的值
        }
    }
}

测试一下:

new MyPromise((resolve, reject) => {
    resolve('1.成功') // {promiseStatus:"fulfilled",promiseResult:"1.成功"}
}) 

new MyPromise((resolve, reject) => { 
    reject('2.失败') // {promiseStatus:"rejected",promiseResult:"2.失败"}
}) 

new MyPromise((resolve, reject) => { 
    resolve('3.成功') // {promiseStatus:"fulfilled",promiseResult:"3.成功"}
    reject('3.失败') // 不会执行
})

step3:

目的:实现then方法,实例状态发生改变时的回调函数

代码解析:

  1. then接受2个参数
    • resolved()后 的回调函数 onFulfilled
    • rejected()后 的回调函数 onRejected
  2. 当调用resolved() , 状态发生改变为 fulfilled 时,执行回调函数 onFulfilled
  3. 当调用rejected() , 状态发生改变为 onRejected 时,执行回调函数 onRejected

代码编写:

class MyPromise {
    constructor(executor) {...}
 
    initValue() {...}
 
    initBind() {...}
 
    resolve(res){...}
 
    reject(err) {...}
 
    then(onFulfilled,onRejected){
        if(this.promiseStatus === 'fulfilled'){
            onFulfilled(this.promiseResult)
        }else if(this.promiseStatus === 'rejected'){
            onRejected(this.promiseResult)
        }
    }
}

测试一下:

new MyPromise((resolve, reject) => {
    resolve('成功')
}).then((res) => {
    console.log('res:',res) // res: 成功
},(err) => {
    console.log('err:',err)
})
 
new MyPromise((resolve, reject) => {
    reject('失败')
}).then((res) => {
    console.log('res:',res)
},(err) => {
    console.log('err:',err) // err: 失败
})

step4:

目的:实现异步调用,让异步代码和同步一样

代码解析:

  1. resolve在setTimeout内执行,还没到resolve或reject方法,then中还是'pending'状态
  2. 采用先存后用,当调用then时,把成功 onFulfilled() 和失败 onRejected()存起来
    • 定义成功回调数组onFulfilledCallback,保存成功 onFulfilled() 的集合
    • 定义失败回调数组onRejectedCallback,保存失败 onRejected() 的集合
  3. 当走到resolve 或者 reject 再循环执行存起来的 回调函数
  • 定义成数组,是因为后续我们需要 then 的链式调用,有多个onFulfilled() 和 onRejected()
  • 所以到resolve和reject时,需要循环执行回调数组。
    • this.onFulfilledCallback.shift(),提取第一个出来,相当于一个 onFulfilled()
    • this.onFulfilledCallback.shift()(this.promiseResult),就相当于 onFulfilled(this.promiseResult)

代码编写:

class MyPromise {
    constructor(executor) {
        this.initValue()
        this.initBind()
        executor(this.resolve, this.reject)
    }
 
    initValue() {
        this.promiseStatus = 'pending' 
        this.promiseResult = null 
        this.onFulfilledCallback = [] // 2.成功回调数组
        this.onRejectedCallback = [] // 2.失败回调数组
    }
 
    initBind() {
        this.resolve = this.resolve.bind(this) 
        this.reject = this.reject.bind(this)
    }
 
    resolve(res) {
        if (this.promiseStatus === 'pending') {
            this.promiseStatus = 'fulfilled'
            this.promiseResult = res
            while(this.onFulfilledCallback.length){ // 3.循环执行
                this.onFulfilledCallback.shift()(this.promiseResult)
            }
        }
 
    }
 
    reject(err) {
        if (this.promiseStatus === 'pending') {
            this.promiseStatus = 'rejected'
            this.promiseResult = err
             while(this.onRejectedCallback.length){//  3.循环执行
                this.onRejectedCallback.shift()(this.promiseResult)
            }
        }
    }
 
    then(onFulfilled,onRejected){
        if(this.promiseStatus === 'fulfilled'){
            onFulfilled(this.promiseResult)
        }else if(this.promiseStatus === 'rejected'){
            onRejected(this.promiseResult)
        }else if(this.promiseStatus === 'pending'){ // 1.settimeout时,这里状态仍为 pengding
            this.onFulfilledCallback.push(onFulfilled.bind(this)) // 2.保存成功 onFulfilled() 的集合
            this.onRejectedCallback.push(onRejected.bind(this))// 2.保存失败 onRejected() 的集合
        }
    }
}

测试一下:

new MyPromise((resolve, reject) => { 
    setTimeout(() => { 
        resolve('成功') 
    },500)
}).then((res) => { 
    console.log('res:',res) // 500ms后 res: 成功
})

step5:

目的:实现then的链式调用,后一个then可以获取到前一个return的值

代码解析:

  1. 要想链式调用,返回的肯定是一个promise对象
  2. 如果值为promise,就看promise是成功还是失败,返回对应的值。只有.then才知道它是成功还是失败
  3. 如果值为非promise,直接成功resolve(x)
  4. 执行Promise A+标准,返回值不能为Promise本身,死循环。(ps:想不到什么情况会返回本身)

代码编写:

class MyPromise {
    constructor(executor) {...}
 
    initValue() {...}
 
    initBind() {...}
 
    resolve(res) {...}
 
    reject(err) {...}
 
    then(onFulfilled, onRejected) {
        let thenPromise = new MyPromise((resolve, reject) => { // 1.返回时promise对象
            const resultPromise = (cb) => { // 提取一个公共方法
                const x = cb(this.promiseResult) // 获取返回值,cb为传入的函数
                if(x === MyPromise){
                    throw new Error('死循环')// 4.A+ 规范
                }
                if(x instanceof MyPromise){ // 2.值为promise
                    x.then(resolve,reject) // 2.只有.then才知道它是成功还是失败
                }else{ // 值为非promise
                    resolve(x) // 3.直接成功返回
                }
            }
            if (this.promiseStatus === 'fulfilled') {
                resultPromise(onFulfilled) // 原本 onFulfilled(this.promiseResult)
            } else if (this.promiseStatus === 'rejected') {
                resultPromise(onRejected) // 原本 onRejected(this.promiseResult)
            } else if (this.promiseStatus === 'pending') {
                this.onFulfilledCallback.push(resultPromise.bind(this, onFulfilled)) 
                this.onRejectedCallback.push(resultPromise.bind(this,onRejected))
                // 原本 this.onFulfilledCallback.push(onFulfilled.bind(this)) 
                // 原本 this.onRejectedCallback.push(onRejected.bind(this))
            }
 
        })
        return thenPromise
    }
}
 

测试一下:

new MyPromise((resolve, reject) => {
   resolve(100)
}).then(res => {
    console.log(res, '第一个then') // 100
    return res * 2
}).then(res => {
    console.log(res, '第二个then') // 200
    return new MyPromise((resolve, reject) => {
        resolve(res + 100)
    })
}).then(res => {
    console.log(res, '第三个then') // 300
})

step6:

目的:执行顺序

代码解析:

  1. Promise.then是微任务,外层执行应该比then要更快
  2. 按这个道理,只需要在then返回得时候执行setTimeout 同为微任务

代码编写:

class MyPromise {
    constructor(executor) {...}
 
    initValue() {...}
 
    initBind() {...}
    resolve(res) {...}
 
    reject(err) {...}
 
    then(onFulfilled, onRejected) {
        let thenPromise = new MyPromise((resolve, reject) => {
            const resultPromise = (cb) => {
                setTimeout(() => {  // 添加setTimeout,形成微任务
                    const x = cb(this.promiseResult)
                    if (x === MyPromise) {
                        throw new Error('死循环')
                    }
                    if (x instanceof MyPromise) {
                        x.then(resolve, reject)
                    } else {
                        resolve(x)
                    }
                })
            }
            if (this.promiseStatus === 'fulfilled') {
                resultPromise(onFulfilled)
            } else if (this.promiseStatus === 'rejected') {
                resultPromise(onRejected)
            } else if (this.promiseStatus === 'pending') {
                this.onFulfilledCallback.push(resultPromise.bind(this, onFulfilled)) 
                this.onRejectedCallback.push(resultPromise.bind(this, onRejected))
            }
 
        })
        return thenPromise
    }
}

测试一下:

new MyPromise((resolve, reject) => { 
    resolve(2)
}).then(res => { 
    console.log(res, 'then微任务后执行:2')
}) 

console.log('外层先执行:1')
// 外层先执行:1
// 2 then微任务后执行:2

step7:

目的:实现值穿透,多个then,最后一个then获取值

代码解析:

  1. 如果有回调函数,并且回调函数为function,即为promise,若不是,则直接传递
    • 若不是,onFulfilled = (val) => val
    • 若不是,onRejected = (err) => { throw err} // 报错
  2. 立即执行函数

代码编写:

class MyPromise {
    constructor(executor) {...}
 
    initValue() {...}
 
    initBind() {...}
    resolve(res) {...}
 
    reject(err) {...}
 
    then(onFulfilled, onRejected) {
        // 做穿透兼容
        onFulfilled = typeof onFulfilled === 'function'?onFulfilled : (val) => val
        onRejected = typeof onRejected === 'function'?onRejected : (err) => { throw err}
        let thenPromise = new MyPromise((resolve, reject) => {
            const resultPromise = (cb) => {
                setTimeout(() => { 
                    const x = cb(this.promiseResult)
                    if (x === MyPromise) {
                        throw new Error('死循环')
                    }
                    if (x instanceof MyPromise) {
                        x.then(resolve, reject)
                    } else {
                        resolve(x)
                    }
                })
            }
            if (this.promiseStatus === 'fulfilled') {
                resultPromise(onFulfilled)
            } else if (this.promiseStatus === 'rejected') {
                resultPromise(onRejected)
            } else if (this.promiseStatus === 'pending') {
                this.onFulfilledCallback.push(resultPromise.bind(this, onFulfilled)) 
                this.onRejectedCallback.push(resultPromise.bind(this, onRejected))
            }
 
        })
        return thenPromise
    }
}

测试一下:

new MyPromise((resolve, reject) => { 
    resolve(2)
}).then().then().then().then().then().then().then((res) => {
    console.log('res:',res) // res: 2
 })

step8:

目的:异常捕获处理,按照A+标准做好异常捕获处理

代码解析:

  1. 异常捕获处理, 会导致promise往reject()走,实现异常捕获

代码编写:

class MyPromise {
    constructor(executor) {
        this.initValue()
        this.initBind()
        // 异常捕获
        try {
            executor(this.resolve, this.reject)
        } catch (e) {
            this.reject(e)
        }
    }
 
    initValue() {...}
 
    initBind() {...}
 
    resolve(res) {...}
 
    reject(err) {...}
 
    then(onFulfilled, onRejected) {
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (val) => val
        onRejected = typeof onRejected === 'function' ? onRejected : (err) => { throw err }
        let thenPromise = new MyPromise((resolve, reject) => {
            const resultPromise = (cb) => {
                setTimeout(() => {
                    try { // 异常捕获
                        const x = cb(this.promiseResult)
                        if (x === MyPromise) {
                            throw new Error('死循环') // 抛出给外层catch接收
                        }
                        if (x instanceof MyPromise) {
                            x.then(resolve, reject)
                        } else {
                            resolve(x)
                        }
                    } catch (e) {
                        this.reject(e)
                        throw new Error(e) // 抛出给下一个then接收
                    }
                })
            }
           ...
        })
        return thenPromise
    }
}

到此为止,promise就完成了


三、手写Promise其他功能

all()

特点

  1. 接受一个Promise数组,数组中如有非Promise项,那么此项当成功
  2. 如果所有Promise都成功,就返回成功的数组
  3. 如果有一个Promise失败,就返回失败的结果

代码解析:

  1. 需要定义一个成功结果的数组 result,和用来计数的变量 count
    • result用来存储对应的值,最后做成功的返回
    • count每遍历一次count++,遍历完成,count === promises长度,即全部成功,返回数组
  2. 当遍历这个 Promise数组
    • 如果是Prmise,就交给.then处理,只有.then才知道成功或失败
    • 如果非Promise,那么此项当成功

代码编写:

class MyPromise {
    constructor(executor) {...}
    initValue() {...}
    initBind() {...}
    resolve(res) {...}
    reject(err) {...}
    then(onFulfilled, onRejected) {...}
 
    // all
    static all(promises) {
        let result = [] // 结果数组
        let count = 0 // 计数
        return new MyPromise((resolve, reject) => {
            const addData = (index, value) => { // 提取公共方法,成功才会走的函数
                result[index] = value // 存储结果
                count++ // 遍历次数+1
                if (count === promises.length) resolve(result) // 代表全成功,返回成功数组
            }
            promises.forEach((promise, index) => {
                if (promise instanceof MyPromise) { // 是否为Promise
                    promise.then((res) => {  // 是,交给then处理
                        addData(index, res) // 成功,走成功存储
                    }, err => reject(err)) // 失败,直接结束,返回失败结果
                } else {
                    addData(index, promise) // 非promise,则这项成功
                }
            })
        })
    }
}

测试一下

--- 成功示例
const p1 = 1
const p2 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve(2)
    },500)
})
const p3 = new MyPromise((resolve, reject) => {
    resolve(3)
})
 
MyPromise.all([p1,p2,p3]).then(val => {
    console.log(val) // [1,2,3]
})

--- 失败示例
const p4 = new MyPromise((resolve, reject) => {
    reject(4)
})

MyPromise.all([p1,p2,p3,p4]).then(val => {
    console.log(val) // 报错,Error: 4
})

rate()

特点

  1. 接受一个Promise数组,数组中如有非Promise项,那么此项当成功
  2. 哪个最快返回,就返回哪个结果

代码解析:

  1. 遍历这个 Promise数组
    • 如果是Prmise,就交给.then处理,只有.then才知道成功或失败
    • 如果非Promise,那么此项当成功

代码编写:

class MyPromise {
    constructor(executor) {...}
    initValue() {...}
    initBind() {...}
    resolve(res) {...}
    reject(err) {...}
    then(onFulfilled, onRejected) {...}
 
    // rate
    static rate(promises) {
        return new MyPromise((resolve,reject) => {
            promises.forEach((promise,index) => {
                if(promise instanceof MyPromise){ 
                    promise.then((res) => { // 是Prmise,交给then
                        resolve(res)
                    },(err) => reject(err))
                }else{
                    resolve(promise)  // 非Prmise,执行成功回调
                }
            })
        })
    }
}

测试一下

const p1 = 1
const p2 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve(2)
    },500)
})
const p3 = new MyPromise((resolve, reject) => {
    resolve(3)
})
 
MyPromise.rate([p2,p3,p1]).then(val => {
    console.log(val) // 1  
})
 
MyPromise.rate([p2,p3]).then(val => {
    console.log(val) // 3
})

allSettled()

特点

  1. 接受一个Promise数组,数组中如有非Promise项,那么此项当成功
  2. 把每个Promise的结果,无论成功失败,集合成数组后返回

代码解析:

  1. 结合all(),需要结果集合result和计数count
    • 由于无论成功失败都需要存储,所以添加一个status进到集合里
  2. 无论成功失败,都不走rejected,当都成功,返回一个完整数组
    • 其实就只是多了一个状态(成功 | 失败)

代码编写:

class MyPromise {
    constructor(executor) {...}
    initValue() {...}
    initBind() {...}
    resolve(res) {...}
    reject(err) {...}
    then(onFulfilled, onRejected) {...}
 
    // allSelect
    static allSelect(promises){
        return new MyPromise((resolve,reject) => {
            const result = [] // 结果集合
            let count = 0 // 计数
            const addData = (status,value,index) => {
                result[index] = {status,value} // 这里需要status,记录状态
                count++// 计数
                if(count === promises.length) resolve(result) // 遍历完成,返回结果
            }
            promises.forEach((promise,index) =>{
                if(promise instanceof MyPromise){
                    promise.then((res) => {
                        addData('fulfilled',res,index) // 成功,记录成功状态
                    },err => {
                         addData('rejected',err,index)// 失败,当成功的去走,记录失败状态
                    })
                }else{
                    addData('fulfilled',promise,index) // 成功,记录成功状态
                }
            })
        })
    }
}

测试一下

const p1 = 1
const p2 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        reject(2)
    },500)
})
const p3 = new MyPromise((resolve, reject) => {
    resolve(3)
})
 
MyPromise.allSelect([p1,p2,p3]).then(val => {
    console.log(val)
    /**[
     * {status:'fulfilled',value:1}
     * {status:'rejected',value:2}
     * {status:'fulfilled',value:3}
     * ]
     */
})

any()

特点

  1. 接受一个Promise数组,数组中如有非Promise项,那么此项当成功
  2. 和all()相反,如果有⼀个Promise成功,则返回这个成功结果
  3. 如果所有Promise都失败,则报错;

代码解析:

  1. 定义一个计数count变量,当count === promises长度,说明全失败,报错
  2. 遍历这个 Promise数组
    • 如果是Prmise,就交给.then处理,只有.then才知道成功或失败
    • 如果非Promise,那么此项当成功,直接不用处理

代码编写:

class MyPromise {
    constructor(executor) {...}
    initValue() {...}
    initBind() {...}
    resolve(res) {...}
    reject(err) {...}
    then(onFulfilled, onRejected) {...}
 
    // any
    static any(promises){
        return new Promise((resolve,reject) => {
            let count = 0 // 计数
            promises.forEach((promise) => {
                promise.then((res) => {
                    resolve(res) // 有一个成功,直接返回
                },err => {
                    count++
                    if(count === promises.length){
                        reject('报错') // 全错,直接报错
                    }
                })
            })
        })
    }
}

测试一下

--- 有一个成功案例
const p2 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        reject(2)
    },500)
})
const p3 = new MyPromise((resolve, reject) => {
    resolve(3)
})
 
MyPromise.any([p2,p3]).then(val => {
    console.log(val) // 3
})
 
--- 全都失败,报错案例
const p4 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        reject(2)
    },500)
})
const p5 = new MyPromise((resolve, reject) => {
    reject(1)
})
 
MyPromise.any([p4,p5]).then(val => {
    console.log(val) // 报错
})

四、总结

动动小手,一起来编写吧~

完整代码

class MyPromise {
    constructor(executor) {
        this.initValue()
        this.initBind()
        // 异常捕获
        try {
            executor(this.resolve, this.reject)
        } catch (e) {
            this.reject(e)
        }
    }
 
    initValue() {
        this.promiseStatus = 'pending'
        this.promiseResult = null
        this.onFulfilledCallback = []
        this.onRejectedCallback = []
    }
 
    initBind() {
        this.resolve = this.resolve.bind(this)
        this.reject = this.reject.bind(this)
    }
 
    resolve(res) {
        if (this.promiseStatus === 'pending') {
            this.promiseStatus = 'fulfilled'
            this.promiseResult = res
            while (this.onFulfilledCallback.length) {
                this.onFulfilledCallback.shift()(this.promiseResult)
            }
        }
 
    }
 
    reject(err) {
        if (this.promiseStatus === 'pending') {
            this.promiseStatus = 'rejected'
            this.promiseResult = err
            while (this.onRejectedCallback.length) {
                this.onRejectedCallback.shift()(this.promiseResult)
            }
        }
    }
 
    then(onFulfilled, onRejected) {
        // 做穿透兼容
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (val) => val
        onRejected = typeof onRejected === 'function' ? onRejected : (err) => { throw err }
        let thenPromise = new MyPromise((resolve, reject) => {
            const resultPromise = (cb) => {
                setTimeout(() => {
                    try {
                        const x = cb(this.promiseResult)
                        if (x === MyPromise) {
                            throw new Error('死循环') // 抛出给外层catch接收
                        }
                        if (x instanceof MyPromise) {
                            x.then(resolve, reject)
                        } else {
                            resolve(x)
                        }
                    } catch (e) {
                        this.reject(e)
                        throw new Error(e) // 抛出给下一个then接收
                    }
                })
            }
            if (this.promiseStatus === 'fulfilled') {
                resultPromise(onFulfilled)
            } else if (this.promiseStatus === 'rejected') {
                resultPromise(onRejected)
            } else if (this.promiseStatus === 'pending') {
                this.onFulfilledCallback.push(resultPromise.bind(this, onFulfilled))
                this.onRejectedCallback.push(resultPromise.bind(this, onRejected))
            }
 
        })
        return thenPromise
    }
 
    // all
    static all(promises) {
        let result = [] // 结果数组
        let count = 0 // 计数
        return new MyPromise((resolve, reject) => {
            const addData = (index, value) => {
                result[index] = value
                count++
                if (count === promises.length) resolve(result)
            }
            promises.forEach((promise, index) => {
                if (promise instanceof MyPromise) {
                    promise.then((res) => {
                        addData(index, res)
                    }, err => reject(err))
                } else {
                    addData(index, promise)
                }
            })
        })
    }
 
    // rate
    static rate(promises) {
        return new MyPromise((resolve,reject) => {
            promises.forEach((promise,index) => {
                if(promise instanceof MyPromise){
                    promise.then((res) => {
                        resolve(res)
                    },(err) => reject(err))
                }else{
                    resolve(promise)
                }
            })
        })
    }
 
    // allSelect
    static allSelect(promises){
        return new MyPromise((resolve,reject) => {
            const result = []
            let count = 0
            const addData = (status,value,index) => {
                result[index] = {status,value}
                count++
                if(count === promises.length) resolve(result)
            }
            promises.forEach((promise,index) =>{
                if(promise instanceof MyPromise){
                    promise.then((res) => {
                        addData('fulfilled',res,index)
                    },err => {
                         addData('rejected',err,index)
                    })
                }else{
                    addData('fulfilled',promise,index)
                }
            })
        })
    }
 
    // any
    static any(promises){
        return new Promise((resolve,reject) => {
            let count = 0
            promises.forEach((promise) => {
                promise.then((res) => {
                    resolve(res)
                },err => {
                    count++
                    if(count === promises.length){
                        reject('报错')
                    }
                })
            })
        })
    }
}