手写promise

 //异步实现的函数
        function runAsyncTask(callback) {
            if (typeof queueMicrotask === 'function') {
                queueMicrotask(callback)
            } else if (typeof MutationObserver === 'function') {
                const mutationObserver = new MutationObserver(callback)
                const oDiv = document.createElement('div')
                mutationOBserver.observe(oDiv, { childList: true })
                oDiv.innerText = 'logggle'
            } else {
                setTimeout(callback, 0)
            }
        }
        //将相同代码封装成函数
        function resolvePromise(p2, x, resolve, reject) {
            if (x === p2) {
                throw new TypeError('Chaining cycle detected for promise #')
            }
            if (x instanceof Promise) {
                x.then(
                    (data) => {
                        resolve(data)
                    },
                    (err) => {
                        reject(err)
                    }
                )
            } else {
                resolve(x)
            }

        }
        //定义Promise三个状态
        const PENDING = 'pending'
        const FULFILLED = 'fulfilled'
        const REJECTED = 'rejectted'
        class Promise {
            status = PENDING
            result = undefined
            #handles = []
            constructor(executor) {
                const resolve = (result) => {
                    if (this.status === PENDING) {
                        this.status = FULFILLED
                        this.result = result
                        this.#handles.forEach(({ onFulfilled }) => {
                            onFulfilled()
                        })
                    }
                }
                const reject = (result) => {
                    if (this.status === PENDING) {
                        this.status = REJECTED
                        this.result = result
                        this.#handles.forEach(({ onRejected }) => {
                            onRejected()
                        })
                    }
                }
                executor(resolve, reject)
            }
            //then 方法的实现
            then(onFulfilled, onRejected) {
                onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (x) => x;
                onRejected = typeof onRejected === 'function' ? onRejected : (x) => {
                    throw x
                }
                const p2 = new Promise((resolve, reject) => {
                    if (this.status === FULFILLED) {
                        runAsyncTask(() => {
                            try {
                                const x = onFulfilled(this.result)
                                resolvePromise(p2, x, resolve, reject)
                            } catch (err) {
                                reject(err)
                            }
                        })
                    } else if (this.status === REJECTED) {
                        runAsyncTask(() => {
                            try {
                                const x = onRejected(this.result)
                                resolvePromise(p2, x, resolve, reject)

                            } catch (err) {
                                reject(err)
                            }
                        })

                    } else {
                        this.#handles.push({

                            onFulfilled: () => {
                                runAsyncTask(() => {
                                    try {
                                        const x = onFulfilled(this.result)
                                        resolvePromise(p2, x, resolve, reject)

                                    } catch (err) {
                                        reject(err)
                                    }
                                })

                            },
                            onRejected: () => {
                                runAsyncTask(() => {
                                    try {
                                        const x = onRejected(this.result)
                                        resolvePromise(p2, x, resolve, reject)

                                    } catch (err) {
                                        reject(err)
                                    }
                                })

                            },

                        })
                    }
                })
                return p2
            }
            //catch方法
            catch(onRejected) {
                return this.then(undefined, onRejected)
            }
            //finally 方法
            finally(onFinally) {
                return this.then(onFinally, onFinally)
            }
            //all方法
            static all(promises) {
          return new Promise((resolve, reject) => {
            // 1 参数不是数组直接让promise失败
            if (!Array.isArray(promises)) {
              return reject(new TypeError('argument  is not iterable'))
            }
            // promises为空数组
            promises.length === 0 && resolve(promises)
            // let count = 0 //  统计成功promise个数
            let res = []
            promises.forEach((promise) => {
              // 2 数组元素不是promise,转成成功的promise
              if (!(promise instanceof Promise)) {
                promise = new Promise((resolve, reject) => {
                  resolve(promise)
                })
              }
              promise.then(
                (data) => {
                  res.push(data)
                  //count++
                  res.length === promises.length && resolve(res)
                },
                (err) => {
                  reject(err)
                }
              )
            })
          })
        }

            //resolve方法
            static resolve(value) {
                if (value instanceof Promise) {
                    return value
                }
                return new Promise((resolve, reject) => {
                    resolve(value)
                })
            }
            //reject方法
            static reject(value) {
                if (value instanceof Promise) {
                    return value
                }
                return new Promise((resolve, reject) => {
                    return reject(value)
                })
            }
            //race方法
            static race(promises) {
                return new Promise((resolve, reject) => {
                    // 1 参数不是数组直接让promise失败
                    if (!Array.isArray(promises)) {
                        return reject(new TypeError('argument  is not iterable'))
                    }
                    promises.forEach((promise) => {
                        Promise.resolve(promise).then(
                            (data) => {
                                resolve(data)
                            },
                            (err) => {
                                reject(err)
                            }
                        )
                    })
                })
            }
            //any方法
            static any(promises) {
                return new Promise((resolve, reject) => {
                    //  1 非数组报错
                    if (!Array.isArray(promises)) {
                        return reject(new TypeError('argument  is not iterable'))
                    }
                    // 2 空数组直接失败
                    promises.length === 0 &&
                        reject(new AggregateError(promises, 'All promises were rejected'))

                    // 3  数组
                    const errors = []
                    promises.forEach((promise) => {
                        Promise.resolve(promise).then(
                            (res) => {
                                resolve(res)
                            },
                            (err) => {
                                errors.push(err)
                                errors.length === promises.length &&
                                    reject(
                                        new AggregateError(errors, 'All promises were rejected')
                                    )
                            }
                        )
                    })
                })
            }
            //allSettled方法
            static allSettled(promises) {
                return new Promise((resolve, reject) => {
                    // 1 参数不是数组直接让promise失败
                    if (!Array.isArray(promises)) {
                        return reject(new TypeError('argument  is not iterable'))
                    }
                    // promises为空数组
                    promises.length === 0 && resolve(promises)
                    let res = []
                    promises.forEach((promise) => {
                        // 2 数组元素不是promise,转成成功的promise
                        if (!(promise instanceof Promise)) {
                            promise = new Promise((resolve, reject) => {
                                resolve(promise)
                            })
                        }
                        promise.then(
                            (data) => {
                                res.push({ status: FULFILLED, value: data })
                                //count++
                                res.length === promises.length && resolve(res)
                            },
                            (err) => {
                                res.push({ status: REJECTED, value: err })
                                res.length === promises.length && resolve(res)
                            }
                        )
                    })
                })
            }
        }


你可能感兴趣的:(js笔记,javascript,前端)