当前位置: 首页 > article >正文

从0开始实现es6 promise类

主要由基础实现和静态类的实现两部分组成。

1 基础实现(不含静态类)

 1.1 使用类实现完成构造函数

        实现代码如下,构造函数传入一个回调函数,定义resolve和reject函数,将两个函数作为参数执行回调函数。

// 1. 使用类实现,完成构造函数
class MyGoPromise{
    constructor(callback){
        const resolve = (result) => {
            console.log(result)
        }
        const reject = (result) => {
            console.log(result)
        }

        callback(resolve, reject)
    }
}

        测试代码如下:

const p = new MyGoPromise((resolve, reject) => {
    resolve("success")
    // reject("fail")
})

 1.2 实现状态(pending fulfilled rejected)及结果

        首先状态在类内直接声明默认值,状态固定为三个,声明为类外的字符串常量使用。实现在reject和resolve调用时候的状态变化(pending -> fulfilled, pending --> rejected)以及结果保存。代码实现如下所示:

// 2. 状态及原因 state(pending fulfilled rejected) result
// 常量最好单独定义,方便维护
const PENDING = "pending"
const FULFILLED = "fulfilled"
const REJECTED = "rejected"
class MyGoPromise{
    state = PENDING
    result = undefined
    constructor(callback){
        const resolve = (result) => {
            // 状态只能从pending变为fulfilled或者rejected
            if(this.state === PENDING){
                this.state = FULFILLED
                this.result = result
            }
        }
        const reject = (result) => {
            if(this.state === PENDING){
                this.state = REJECTED
                this.result = result
            }
        }
        callback(resolve, reject)
    }
}

        测试代码如下:

const p = new MyGoPromise((resolve, reject) => {
    resolve("success")
    // reject("fail")
})
console.log(p)

 1.3 then的基础实现

  1.3.1 then的成功以及失败回调实现(同步)

        then接收两个回调函数,成功回调以及失败的回调,通过查阅文档得知传入非函数时,成功返回为x => x,失败返回为 x => throw x。然后根据状态执行相应的回调函数。then实现的代码如下:

then(onFulFilled, onRejected){
        onFulFilled = typeof onFulFilled === "function" ? onFulFilled : x => x
        onRejected = typeof onRejected === "function" ? onRejected : e => {throw e}
        if(this.state === FULFILLED){
            onFulFilled(this.result)
        }
        else if(this.state === REJECTED){
            onRejected(this.result)
        }
    }

        测试代码如下所示:

const p = new MyGoPromise((resolve, reject) => {
    // resolve("success")
    reject("fail")
})

p.then(res => {console.log(res)}, err => {console.log(err)})
console.log(p)

  1.3.2 then的异步支持以及多次调用

        之前的then执行的都是同步任务,需要加入对如setTimeout等异步执行的支持,修改then函数,增加判断条件pending,成立将回调暂存到隐私函数handlers中,等到rejecet或resolve时再执行,修改的代码如下(包含then和reject和resolve的调用逻辑的修改):

constructor(callback){
        const resolve = (result) => {
            // 状态只能从pending变为fulfilled或者rejected
            if(this.state === PENDING){
                this.state = FULFILLED
                this.result = result
                this.#handlers.forEach(({onFulFilled}) => {onFulFilled(this.result)})
            }
        }
        const reject = (result) => {
            if(this.state === PENDING){
                this.state = REJECTED
                this.result = result
                this.#handlers.forEach(({onRejected}) => {onRejected(this.result)})
            }
        }

        callback(resolve, reject)
    }

then(onFulFilled, onRejected){
        // 当传入的值不是函数时,需要按照以下两种形式返回
        onFulFilled = typeof onFulFilled === "function" ? onFulFilled : x => x
        onRejected = typeof onRejected === "function" ? onRejected : e => {throw e}
        if(this.state === FULFILLED){
            onFulFilled(this.result)
        }
        else if(this.state === REJECTED){
            onRejected(this.result)
        }
        else{
            this.#handlers.push({
                onFulFilled,
                onRejected
            })
        }
    }
}

 1.4 异步任务

        当我们使用下述代码测试我们已经实现的内容时会发现输出的顺序错误,代码如下所示:

// !!! 输出顺序有误 原生Promise输出为 start end success
// !!! 自定义Promise输出为 start success end
// 所以需要引入异步任务 选用核心API queueMicrotask MutationObserver setTimeout
console.log("start")
const p = new MyGoPromise((resolve, reject) => {
    resolve("success")
})
p.then(res => console.log(res))
console.log("end")

  1.4.1 异步主要API

        1. queueMicrotask函数直接传入回调函数即可执行

console.log("start")
queueMicrotask(()=>{
    console.log("queueMicrotask")
})
console.log("end")

        2.  MutationObserver notice:only works in browser 子节点改变就会执行

console.log("start")
const obs = new MutationObserver(()=>{
    console.log("MutationObserver")
})

const divNode = document.createElement("div")
obs.observe(divNode, {childList: true})
divNode.innerHTML = "MyGo!!!!!"
console.log("end")

        3. setTimeout(callback, 0) 

  1.4.2  异步任务实现

        将异步任务执行封装成全局函数调用,用于判断以上三种异步实现浏览器是否支持,实现的runAsyncTask函数如下所示:

function runAsyncTask(callback){
    if(typeof queueMicrotask === "function"){
        queueMicrotask(callback)
    }else if(typeof MutationObserver === "function"){
        const obs = new MutationObserver(callback)
        const divNode = document.createElement("div")
        obs.observe(divNode, {childList: true})
        divNode.innerHTML = "MyGo!!!!!"
    }else{
        setTimeout(callback, 0)
    }
}

        修改then函数逻辑,将回调函数封装成异步任务执行,代码如下:

then(onFulFilled, onRejected){
        // 当传入的值不是函数时,需要按照以下两种形式返回
        onFulFilled = typeof onFulFilled === "function" ? onFulFilled : x => x
        onRejected = typeof onRejected === "function" ? onRejected : e => {throw e}
        if(this.state === FULFILLED){
            // 异步任务
            runAsyncTask(()=>{
                onFulFilled(this.result)
            })    
        }
        else if(this.state === REJECTED){
            // 异步任务
            runAsyncTask(()=>{
                onRejected(this.result)
            })
        }
        else{
            this.#handlers.push({
                onFulFilled:() => {
                    // 异步任务
                    runAsyncTask(()=>{
                        onFulFilled(this.result)
                    })
                },
                onRejected: () =>{
                    // 异步任务
                    runAsyncTask(() => {
                        onRejected(this.result)
                    })
                }
            })
        }
    }

 1.5 链式编程

        链式编程实现then的链式调用,错误处理,返回值处理(通常分为返回Promise 正常值 多重引用)。

  1.5.1 处理异常和普通返回值(fulfilled state)

        首先实现链式调用,使用new再then函数中创建一个全新的Promise对象,将对象返回,将之前then函数的执行逻辑放入新的Promise的回调函数当中(因为会立即执行),单独处理fulfilled分支使用try...catch...捕获错误,使用reject返回错误,获取回调函数返回值,然后resolve,代码如下:

    then(onFulFilled, onRejected){
        // 当传入的值不是函数时,需要按照以下两种形式返回
        onFulFilled = typeof onFulFilled === "function" ? onFulFilled : x => x
        onRejected = typeof onRejected === "function" ? onRejected : e => {throw e}

        // 在newPromise时传入的回调函数会立即执行
        const newPromise = new MyGoPromise((resolve, reject) => {
            if(this.state === FULFILLED){
                // 异步任务
                runAsyncTask(()=>{
                    try {
                        const x = onFulFilled(this.result)
                        resolve(x)
                    } catch (error) {
                        reject(error) 
                    }
                }) 
              
            }
            else if(this.state === REJECTED){
                // 异步任务
                runAsyncTask(()=>{
                    onRejected(this.result)
                })
            }
            else{
                this.#handlers.push({
                    onFulFilled:() => {
                        // 异步任务
                        runAsyncTask(()=>{
                            onFulFilled(this.result)
                        })
                    },
                    onRejected: () =>{
                        // 异步任务
                        runAsyncTask(() => {
                            onRejected(this.result)
                        })
                    }
                })
            }
        })
        return newPromise
    }

        测试代码如下:

const p = new MyGoPromise((resolve, reject) => {
    resolve(1)
})

p.then(res =>{
    console.log(res)
    // throw "error layer1"
    return 100
}).then(res =>{
    console.log(res + " sub")
}, err =>{
    console.log(err + "sub")
})

  1.5.2 处理返回Promise对象 (fulfilled state)

        使用instance of判断,promise对象调用then方法处理,代码如下所示:

    then(onFulFilled, onRejected){
        // 当传入的值不是函数时,需要按照以下两种形式返回
        onFulFilled = typeof onFulFilled === "function" ? onFulFilled : x => x
        onRejected = typeof onRejected === "function" ? onRejected : e => {throw e}

        // 在newPromise时传入的回调函数会立即执行
        const newPromise = new MyGoPromise((resolve, reject) => {
            if(this.state === FULFILLED){
                // 异步任务
                runAsyncTask(()=>{
                    try {
                        const x = onFulFilled(this.result)
                        // 在这里处理Promise对象根据结果提交
                        if(x instanceof MyGoPromise){
                            x.then(res =>{
                                resolve(res)
                            }, err =>{
                                reject(err)
                            })
                        }else{
                            resolve(x)
                        }

                    } catch (error) {
                        reject(error) 
                    }
                }) 
              
            }
            else if(this.state === REJECTED){
                // 异步任务
                runAsyncTask(()=>{
                    onRejected(this.result)
                })
            }
            else{
                this.#handlers.push({
                    onFulFilled:() => {
                        // 异步任务
                        runAsyncTask(()=>{
                            onFulFilled(this.result)
                        })
                    },
                    onRejected: () =>{
                        // 异步任务
                        runAsyncTask(() => {
                            onRejected(this.result)
                        })
                    }
                })
            }
        })
        return newPromise
    }
}

        测试代码如下:

// 测试代码 -- 返回Promise对象
const p = new MyGoPromise((resolve, reject) => {
    resolve(1)
})

p.then(res =>{
    return new MyGoPromise((resolve, reject) => {
        // resolve(2)
        reject("error layer2")
    })
}).then(res =>{
    // 要拿到上一个Promise resolve的结果
    console.log(res + " sub")
}, err =>{
    console.log(err + "sub")
})

  1.5.3 处理重复引用 (fulfilled state)

        只需要判断我们取到的回调函数的返回值和创建的新的promise对象是否一致即可,代码(包含测试代码)如下所示:

if(x === newPromise)
{
    throw new TypeError("Chaining cycle detected for promise")
}


// test code
const p = new MyGoPromise((resolve, reject) => {
    resolve(1)
})

const p2 = p.then((res)=>{
    return p2
})

  1.5.4 处理rejected state 封装函数

        遵循同一套逻辑,首先进行错误处理,然后判断重复引用和回调结果是否是Promise对象,所以封装函数如下:

function resolvePromise(newPromise, x, resolve, reject){
    if(x === newPromise)
        {
            throw new TypeError("Chaining cycle detected for promise")
        }
        if(x instanceof MyGoPromise){
            x.then(res =>{
                resolve(res)
            }, err =>{
                reject(err)
            })
        }else{
            resolve(x)
        }
}

         使用封装函数,代码如下:

    then(onFulFilled, onRejected){
        // 当传入的值不是函数时,需要按照以下两种形式返回
        onFulFilled = typeof onFulFilled === "function" ? onFulFilled : x => x
        onRejected = typeof onRejected === "function" ? onRejected : e => {throw e}

        // 在newPromise时传入的回调函数会立即执行
        const newPromise = new MyGoPromise((resolve, reject) => {
            if(this.state === FULFILLED){
                // 异步任务
                runAsyncTask(()=>{
                    try {
                        const x = onFulFilled(this.result)
                        resolvePromise(newPromise, x, resolve, reject)
                    } catch (error) {
                        reject(error) 
                    }
                }) 
              
            }
            else if(this.state === REJECTED){
                // 异步任务
                runAsyncTask(()=>{
                    try {
                        const x = onRejected(this.result)
                        resolvePromise(newPromise, x, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                    
                })
            }
            else{
                this.#handlers.push({
                    onFulFilled:() => {
                        // 异步任务
                        runAsyncTask(()=>{
                            onFulFilled(this.result)
                        })
                    },
                    onRejected: () =>{
                        // 异步任务
                        runAsyncTask(() => {
                            onRejected(this.result)
                        })
                    }
                })
            }
        })
        return newPromise
    }

        测试代码如下:

// 测试代码
const p = new MyGoPromise((resolve, reject) => {
    reject(1)
})

const p2 = p.then(undefined, res =>{
    // return 2
    // return p2
    throw "error"
    // return new MyGoPromise((resolve, reject) => {
    //     resolve(3)
    // })
})

p2.then((res)=>{
    console.log("p2-res: ", res)
}, err =>(
    console.log("p2-err: ", err)
))

  1.5.5 处理pending state 调用函数

        和处理fulfilled和rejected状态一样,代码如下所示:

    then(onFulFilled, onRejected){
        // 当传入的值不是函数时,需要按照以下两种形式返回
        onFulFilled = typeof onFulFilled === "function" ? onFulFilled : x => x
        onRejected = typeof onRejected === "function" ? onRejected : e => {throw e}

        // 在newPromise时传入的回调函数会立即执行
        const newPromise = new MyGoPromise((resolve, reject) => {
            if(this.state === FULFILLED){
                // 异步任务
                runAsyncTask(()=>{
                    try {
                        const x = onFulFilled(this.result)
                        resolvePromise(newPromise, x, resolve, reject)
                    } catch (error) {
                        reject(error) 
                    }
                }) 
              
            }
            else if(this.state === REJECTED){
                // 异步任务
                runAsyncTask(()=>{
                    try {
                        const x = onRejected(this.result)
                        resolvePromise(newPromise, x, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                    
                })
            }
            else{
                this.#handlers.push({
                    onFulFilled:() => {
                        // 异步任务
                        runAsyncTask(()=>{
                            try {
                                const x = onFulFilled(this.result)
                                resolvePromise(newPromise, x, resolve, reject)
                            } catch (error) {
                                reject(error)
                            }
                        })
                    },
                    onRejected: () =>{
                        // 异步任务
                        runAsyncTask(() => {
                            try {
                                const x = onRejected(this.result)
                                resolvePromise(newPromise, x, resolve, reject)
                            } catch (error) {
                                reject(error)
                            }
                        })
                    }
                })
            }
        })
        return newPromise
    }

        测试代码如下:

// 测试代码
const p = new MyGoPromise((resolve, reject) => {
    setTimeout(()=>{
        resolve("success")
    }, 2000)
})

const p2 = p.then(res =>{
    // return 2
    // return p2
    throw "error"
    // return new MyGoPromise((resolve, reject) => {
    //     resolve(3)
    // })
})

p2.then((res)=>{
    console.log("p2-res: ", res)
}, err =>(
    console.log("p2-err: ", err)
))

1.6 实现catch方法

        处理错误,相当于调用then方法,但是还要处理new Promise回调里面的函数错误,修改部分代码如下:

    
//新增catch函数
catch(onRejected){
        // 相当于变相调用then方法
    return this.then(undefined, onRejected)
}

// 处理实例化时的异常
    try {
        callback(resolve, reject)
    } catch (error) {
            // 处理实例化时的异常
        reject(error)
    }

        测试的代码如下所示:

// 测试代码
const p = new MyGoPromise((resolve, reject) => {
    throw "error"
    // reject("reject-error")
})

p.then((res)=>{
    console.log("p-res: ", res)
}).catch(err =>(
    console.log("p-catch-err: ", err)
))

 1.7 finally实现

        不管是什么状态,最终都要执行的回调函数,也是调用then方法,只是不管是成功回调还是失败回调都是同一个回调函数,实现代码如下:

finally(onFinally){
    return this.then(onFinally, onFinally)
}

        测试代码如下:

const p = new MyGoPromise((resolve, reject) => {
    throw "error"
    // reject("reject-error")
})

p.then((res)=>{
    console.log("p-res: ", res)
}).catch(err =>(
    console.log("p-catch-err: ", err)
)).finally(()=>{
    console.log("finally")
})

2 静态类方法实现

 2.1 resolve方法实现

        调用该方法将传入的值(非Promise)转换为fulfilled状态的Promise返回,如果传入Promise直接返回。

static resolve(value){
    if(value instanceof MyGoPromise){
        return value
    }

    return new MyGoPromise((resolve) => {
        resolve(value)
    })
}

        测试代码如下:

// 测试代码
const p = MyGoPromise.resolve(
    new MyGoPromise((resolve, reject) => {
        // resolve("success")
        reject("reject-error")
    })
).then(res =>{
    console.log("res: ", res)
}, err =>{
    console.log("err: ", err)
})

 2.2 reject方法实现

        不管传入什么值,直接将返回值作为原因返回rejected状态的promise,实现的代码如下:

static reject(value){
    return new MyGoPromise((resolve, reject) => {
        reject(value)
    })
}

        测试代码如下:

// 测试代码
MyGoPromise.reject("reject-error").catch(err =>{
    console.log("err: ", err)
})

 2.3 race方法实现

        race接收一个数组作为参数,返回最先完成(fulfilled)的promise对象,如果传入不是数组则拨错,实现代码如下:

static race(promises){
    return new MyGoPromise((resolve, reject) => {
        if(!Array.isArray(promises)){
            reject(new TypeError("Argument is not iterable"))
        }

        promises.forEach(promise =>{
            MyGoPromise.resolve(promise).then(res => {
                resolve(res)
            }, err =>{
                reject(err)
            })
        })
    })
}

        测试代码如下:

// 测试代码
const p1 = new MyGoPromise((resolve, reject) => {
    setTimeout(()=>{
        resolve("success")
    }, 2000)
})

const p2 = new MyGoPromise((resolve, reject) => {
    setTimeout(()=>{
        reject("reject-error")
    }, 1000)
})

MyGoPromise.race([p1, p2]).then(res =>{
    console.log("res: ", res)
}, err =>{
    console.log("err: ", err)
})

 2.4 all方法实现

        也是传入一个数组,有一个错误就reject,全部成功返回一个数组(按顺序),如果传入空数组直接返回空数组结果,实现代码如下:

static all(promises){
    // 1.返回Promise实例
    // 2.判断是否时数组
    // 3. 判断是否为空数组,空数组直接兑现
    // 4. 处理全部兑现 v,k 存储数据, count计数判断是否拒绝
    // 5. 处理拒绝 直接拒绝即可
    return new MyGoPromise((resolve, reject) => {
        if(!Array.isArray(promises)){
            reject(new TypeError("Argument is not iterable"))
        }
        promises.length === 0 && resolve([])

        let count = 0
        const result = []
        promises.forEach((promise, index) => {
            MyGoPromise.resolve(promise).then(res =>{
                result[index] = res
                count ++
                count === promises.length && resolve(result)
            }, err =>{
                reject(err)
            })
        })
    }) 
}

        测试代码如下所示:

// 测试代码
const p1 = new MyGoPromise((resolve, reject) => {
    setTimeout(()=>{
        resolve("success 1")
    }, 2000)
})

const p2 = new MyGoPromise((resolve, reject) => {
    setTimeout(()=>{
        resolve("success 2")
    }, 1000)
})

MyGoPromise.all([p1, p2]).then(res =>{
    console.log("res: ", res)
}, err =>{
    console.log("err: ", err)
})

 2.5 allsettled方法实现

        无论成功还是失败,都是返回一个对象数组,数组中存储state和value以及reason,基本照搬all方法的实现,代码如下:

static allsettled(promises){
    return new MyGoPromise((resolve, reject) => {
        if(!Array.isArray(promises)){
            reject(new TypeError("Argument is not iterable"))
        }
        promises.length === 0 && resolve([])

        let count = 0
        const result = []
        promises.forEach((promise, index) => {
            MyGoPromise.resolve(promise).then(res =>{
                result[index] = {
                    value: res,
                    status: "fulfilled",
                }
                count ++
                count === promises.length && resolve(result)
            }, err =>{
                result[index] = {
                    reason: err,
                    status: "rejected"
                }
                count ++
                count === promises.length && resolve(result)
            })
        })
    }) 
}

        测试代码如下所示:

// 测试代码
const p1 = new MyGoPromise((resolve, reject) => {
    setTimeout(()=>{
        resolve("success 1")
    }, 2000)
})

const p2 = new MyGoPromise((resolve, reject) => {
    setTimeout(()=>{
        reject("success 2")
    }, 1000)
})

MyGoPromise.allsettled([1, p1, p2]).then(res =>{
    // 会打印成功和失败的结果
    console.log("res: ", res)
}, err =>{
    console.log("err: ", err)
})

 2.6 any方法实现

        任意一个成功就返回成功,全部失败才返回失败,和all反着来,但是在any方法中,如果传入空数组也会有aggregate的报错,是新代码如下:

static any(promises){
    return new MyGoPromise((resolve, reject)=>{
        if(!Array.isArray(promises)){
            reject(new TypeError("Argument is not iterable"))
        }
        promises.length === 0 && reject(new AggregateError([]))

        let count = 0
        const errors = []

        promises.forEach((promise, index)=>{
            MyGoPromise.resolve(promise).then(res => {
                resolve(res)
            }, err => {
                errors[index] = err
                count ++
                count === promises.length && reject(new AggregateError(errors))
            })
        })
    })
}

        测试代码如下所示:

// 测试代码
const p1 = new MyGoPromise((resolve, reject) => {
    setTimeout(()=>{
        resolve("success 1")
    }, 2000)
})

const p2 = new MyGoPromise((resolve, reject) => {
    setTimeout(()=>{
        reject("success 2")
    }, 1000)
})

MyGoPromise.any([p1, p2, MyGoPromise.reject(1)]).then(res =>{
    // 会打印第一个成功的结果 1
    console.log("res: ", res)
}, err =>{
    console.log("err: ", err)
})

3 完整代码展示

function runAsyncTask(callback){
    if(typeof queueMicrotask === "function"){
        queueMicrotask(callback)
    }else if(typeof MutationObserver === "function"){
        const obs = new MutationObserver(callback)
        const divNode = document.createElement("div")
        obs.observe(divNode, {childList: true})
        divNode.innerHTML = "MyGo!!!!!"
    }else{
        setTimeout(callback, 0)
    }
}

function resolvePromise(newPromise, x, resolve, reject){
    if(x === newPromise)
        {
            throw new TypeError("Chaining cycle detected for promise")
        }
        if(x instanceof MyGoPromise){
            x.then(res =>{
                resolve(res)
            }, err =>{
                reject(err)
            })
        }else{
            resolve(x)
        }
}

const PENDING = "pending"
const FULFILLED = "fulfilled"
const REJECTED = "rejected"
class MyGoPromise{
    state = PENDING
    result = undefined
    // 使用对象数组保存pending时候的失败调用和成功调用
    #handlers = []
    constructor(callback){
        const resolve = (result) => {
            // 状态只能从pending变为fulfilled或者rejected
            if(this.state === PENDING){
                this.state = FULFILLED
                this.result = result
                this.#handlers.forEach(({onFulFilled}) => {onFulFilled(this.result)})
            }
        }
        const reject = (result) => {
            if(this.state === PENDING){
                this.state = REJECTED
                this.result = result
                this.#handlers.forEach(({onRejected}) => {onRejected(this.result)})
            }
        }

        try {
            callback(resolve, reject)
        } catch (error) {
            // 处理实例化时的异常
            reject(error)
        }
        
    }

    then(onFulFilled, onRejected){
        // 当传入的值不是函数时,需要按照以下两种形式返回
        onFulFilled = typeof onFulFilled === "function" ? onFulFilled : x => x
        onRejected = typeof onRejected === "function" ? onRejected : e => {throw e}

        // 在newPromise时传入的回调函数会立即执行
        const newPromise = new MyGoPromise((resolve, reject) => {
            if(this.state === FULFILLED){
                // 异步任务
                runAsyncTask(()=>{
                    try {
                        const x = onFulFilled(this.result)
                        resolvePromise(newPromise, x, resolve, reject)
                    } catch (error) {
                        reject(error) 
                    }
                }) 
              
            }
            else if(this.state === REJECTED){
                // 异步任务
                runAsyncTask(()=>{
                    try {
                        const x = onRejected(this.result)
                        resolvePromise(newPromise, x, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                    
                })
            }
            else{
                this.#handlers.push({
                    onFulFilled:() => {
                        // 异步任务
                        runAsyncTask(()=>{
                            try {
                                const x = onFulFilled(this.result)
                                resolvePromise(newPromise, x, resolve, reject)
                            } catch (error) {
                                reject(error)
                            }
                        })
                    },
                    onRejected: () =>{
                        // 异步任务
                        runAsyncTask(() => {
                            try {
                                const x = onRejected(this.result)
                                resolvePromise(newPromise, x, resolve, reject)
                            } catch (error) {
                                reject(error)
                            }
                        })
                    }
                })
            }
        })
        return newPromise
    }

    catch(onRejected){
        // 相当于变相调用then方法
        return this.then(undefined, onRejected)
    }

    finally(onFinally){
        return this.then(onFinally, onFinally)
    }

    static resolve(value){
        if(value instanceof MyGoPromise){
            return value
        }

        return new MyGoPromise((resolve) => {
            resolve(value)
        })
    }

    static reject(value){
        return new MyGoPromise((resolve, reject) => {
            reject(value)
        })
    }

    static race(promises){
        return new MyGoPromise((resolve, reject) => {
            if(!Array.isArray(promises)){
                reject(new TypeError("Argument is not iterable"))
            }

            promises.forEach(promise =>{
                MyGoPromise.resolve(promise).then(res => {
                    resolve(res)
                }, err =>{
                    reject(err)
                })
            })
        })
    }

    static all(promises){
        // 1.返回Promise实例
        // 2.判断是否时数组
        // 3. 判断是否为空数组,空数组直接兑现
        // 4. 处理全部兑现 v,k 存储数据, count计数判断是否拒绝
        // 5. 处理拒绝 直接拒绝即可
        return new MyGoPromise((resolve, reject) => {
            if(!Array.isArray(promises)){
                reject(new TypeError("Argument is not iterable"))
            }
            promises.length === 0 && resolve([])

            let count = 0
            const result = []
            promises.forEach((promise, index) => {
                MyGoPromise.resolve(promise).then(res =>{
                    result[index] = res
                    count ++
                    count === promises.length && resolve(result)
                }, err =>{
                    reject(err)
                })
            })
        }) 
    }


    static allsettled(promises){
        return new MyGoPromise((resolve, reject) => {
            if(!Array.isArray(promises)){
                reject(new TypeError("Argument is not iterable"))
            }
            promises.length === 0 && resolve([])

            let count = 0
            const result = []
            promises.forEach((promise, index) => {
                MyGoPromise.resolve(promise).then(res =>{
                    result[index] = {
                        value: res,
                        status: "fulfilled",
                    }
                    count ++
                    count === promises.length && resolve(result)
                }, err =>{
                    result[index] = {
                        reason: err,
                        status: "rejected"
                    }
                    count ++
                    count === promises.length && resolve(result)
                })
            })
        }) 
    }

    static any(promises){
        return new MyGoPromise((resolve, reject)=>{
            if(!Array.isArray(promises)){
                reject(new TypeError("Argument is not iterable"))
            }
            promises.length === 0 && reject(new AggregateError([]))

            let count = 0
            const errors = []

            promises.forEach((promise, index)=>{
                MyGoPromise.resolve(promise).then(res => {
                    resolve(res)
                }, err => {
                    errors[index] = err
                    count ++
                    count === promises.length && reject(new AggregateError(errors))
                })
            })
        })
    }

}


http://www.kler.cn/news/329607.html

相关文章:

  • 【可答疑】基于51单片机的体温心率血氧检测系统(含仿真、代码、报告等)
  • I2C-Tools的安装与使用方法(详解,一篇教会你熟练使用)
  • 数据库索引和磁盘的关系大揭秘
  • Leetcode 3307. Find the K-th Character in String Game II
  • 无线通信系统仿真与原型设计:MATLAB实践指南
  • LDRA Testbed(TBrun)软件集成测试(部件测试)_操作指南
  • postgresql僵尸进程的处理思路
  • 一文带你入门客制化键盘,打造专属打字利器
  • 大数据常问八股文面试题【数据倾斜,现象、本质原因、解决方案】
  • OpenCV视频I/O(3)视频采集类VideoCapture之获取当前使用的视频捕获 API 后端的名称函数getBackendName()的使用
  • 【含文档】基于Springboot+微信小程序 的中心医院用户移动端(含源码+数据库+lw)
  • vim(1) -- 环境配置
  • 电脑usb接口封禁如何实现?5种禁用USB接口的方法分享!(第一种你GET了吗?)
  • PLMN NR cell
  • Nature Machine Intelligence 基于强化学习的扑翼无人机机翼应变飞行控制
  • 网盘能否作为FTP替代产品?企业该如何进行FTP国产化替代?
  • 深度优先搜索算法改进:分类与打印有向图中的每条边
  • 【Canvas与艺术】六鱼六燕铁艺壁画
  • 微服务 OpenFeign 解析部署使用全流程
  • PHP include和require的区别
  • TiDB 6.0 Book Rush | TiDB 和 Python 的 CRUD 应用开发实践
  • 使用ESP8266扫描WiFi列表
  • H.264编解码工具 - Intel Quick Sync Video
  • 类C语言补充
  • 如何在 macOS(MacBook Pro、Air 和 iMac)上恢复未保存的 Word 文档
  • 灵当CRM index.php接口SQL注入漏洞复现 [附POC]
  • 一文上手SpringSecurity【五】
  • 前端动态创建svg不起效果?
  • 鸿蒙开发:自制原生下拉框
  • 【网络安全 | JAVA代码审计】基础安全问题和解决方法初探