promise的使用和手写

本文详细介绍了Promise的定义、状态变化、常用方法如then、catch、finally,以及微任务和宏任务的特点。同时探讨了Promise的特殊场景和使用注意事项,并提供了手写Promise的实践,包括状态管理、错误捕获和静态方法的实现。
摘要由CSDN通过智能技术生成

promise定义

b站同步视频链接:
https://www.bilibili.com/video/BV1LN4y1K7Zt/spm_id_from=333.999.0.0&vd_source=92327fe692859effd50d35de710bd8ef

promise的含义

一个 Promise 对象代表一个在这个 promise 被创建出来时不一定已知值的代理。它让你能够把异步操作最终的成功返回值或者失败原因和相应的处理程序关联起来。这样使得异步方法可以像同步方法那样返回值:异步方法并不会立即返回最终的值,而是会返回一个 promise,以便在未来某个时候把值交给使用者。

一个 Promise 必然处于以下几种状态之一:

  • 待定(pending):初始状态,既没有被兑现,也没有被拒绝。
  • 已兑现(fulfilled):意味着操作成功完成。
  • 已拒绝(rejected):意味着操作失败。

待定状态的 Promise 对象要么会通过一个值被兑现,要么会通过一个原因(错误)被拒绝。当这些情况之一发生时,我们用 promise 的 then 方法排列起来的相关处理程序就会被调用。如果 promise 在一个相应的处理程序被绑定时就已经被兑现或被拒绝了,那么这个处理程序也同样会被调用,因此在完成异步操作和绑定处理方法之间不存在竞态条件。

Promise对象有以下两个特点。

  • Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态
  • 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了
    在这里插入图片描述

基本用法

const promise = new Promise(function(resolve, reject) {
  // ... some code
  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

Promise.prototype.then()

Promise 实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。它的作用是为 Promise 实例添加状态改变时的回调函数。前面说过,then方法的第一个参数是resolved状态的回调函数,第二个参数(可选)是rejected状态的回调函数。

then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。

getJSON("/posts.json").then(function(json) {
  return json.post;
}).then(function(post) {
  // ...
});

采用链式的then,可以指定一组按照次序调用的回调函数。这时,前一个回调函数,有可能返回的还是一个Promise对象(即有异步操作),这时后一个回调函数,就会等待该Promise对象的状态发生变化,才会被调用。

getJSON("/post/1.json").then(function(post) {
  return getJSON(post.commentURL);
}).then(function (comments) {
  console.log("resolved: ", comments);
}, function (err){
  console.log("rejected: ", err);
});

promise.then执行时机:微任务

Promise.prototype.catch()

当 Promise 被 rejected 时,被调用的一个Function。 该函数拥有一个参数:reason rejection 的原因。如果 onRejected 抛出一个错误或返回一个本身失败的 Promise , 通过 catch() 返回的 Promise 被 rejected;否则,它将显示为成功(resolved)。

var p1 = new Promise(function(resolve, reject) {
  resolve('Success');
});

p1.then(function(value) {
  console.log(value); // "Success!"
  throw 'oh, no!';
}).catch(function(e) {
  console.log(e); // "oh, no!"
}).then(function(){
  console.log('after a catch the chain is restored');
}, function () {
  console.log('Not fired due to the catch');
});

Promise.prototype.finally()

finally() 方法返回一个 Promise。在 promise 结束时,无论结果是 fulfilled 或者是 rejected,都会执行指定的回调函数。这为在 Promise 是否成功完成后都需要执行的代码提供了一种方式。这避免了同样的语句需要在 then() 和 catch() 中各写一次的情况。

微任务和宏任务特点

先执行同步任务,遇到微任务和宏任务依次压入任务队列,同步任务执行完成之后,然后执行宏任务,但是每次执行宏任务,需要检查是否含有微任务,有微任务则执行微任务。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ky7EZMmi-1663835703490)(精通promise.assets/image-20220916193056628.png)]

静态方法

Promise.resolve()

返回一个以给定值解析后的 Promise对象。如果这个值是一个 promise ,那么将返回这个 promise ;如果这个值是 thenable(即带有 ["then" ]方法),返回的 promise 会“跟随”这个 thenable 的对象,采用它的最终状态;否则返回的 promise 将以此值完成。此函数将类 promise 对象的多层嵌套展平。

Promise.resolve("Success").then(function(value) {
  console.log(value); // "Success"
}, function(value) {
  // 不会被调用
});

Promise.reject()

Promise.reject() 方法返回一个带有拒绝原因的 Promise 对象。

Promise.reject(new Error('fail')).then(function() {
  // not called
}, function(error) {
  console.error(error); // Stacktrace
});

Promise.all()

Promise.all() 方法接收一个 promise 的 iterable (可迭代的)类型的输入,并且只返回一个Promise实例, 那个输入的所有 promise 的 resolve 回调的结果是一个数组。这个Promise的 resolve 回调执行是在所有输入的 promise 的 resolve 回调都结束,或者输入的 iterable 里没有 promise 了的时候。它的 reject 回调执行是,只要任何一个输入的 promise 的 reject 回调执行或者输入不合法的 promise 就会立即抛出错误,并且 reject 的是第一个抛出的错误信息。

  • 如果传入的参数是一个空的可迭代对象,则返回一个已完成(already resolved)状态的 Promise
  • 如果传入的参数不包含任何 promise,则返回一个异步完成(asynchronously resolved)Promise
  • 其它情况下返回一个处理中(pending)的Promise。这个返回的 promise 之后会在所有的 promise 都完成或有一个 promise 失败时异步地变为完成或失败。 见下方关于“Promise.all 的异步或同步”示例。返回值将会按照参数内的 promise 顺序排列,而不是由调用 promise 的完成顺序决定。
var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([p1, p2, p3]).then(values => {
  console.log(values); // [3, 1337, "foo"]
});

Promise.allSettled()

Promise.allSettled() 方法返回一个在所有给定的 promise 都已经fulfilledrejected后的 promise,并带有一个对象数组,每个对象表示对应的 promise 结果。

const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = [promise1, promise2];

Promise.allSettled(promises).
  then((results) => console.log(result));

Promise.race() 返回第一个状态改变的promise结果

**Promise.race(iterable) **方法返回一个 promise,一旦迭代器中的某个 promise 解决或拒绝,返回的 promise 就会解决或拒绝。

race 函数返回一个 Promise,它将与第一个传递的 promise 相同的完成方式被完成。它可以是完成( resolves),也可以是失败(rejects),这要取决于第一个完成的方式是两个中的哪个

var p1 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 500, "one");
});
var p2 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 100, "two");
});

Promise.race([p1, p2]).then(function(value) {
  console.log(value); // "two"
  // 两个都完成,但 p2 更快
});

var p3 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 100, "three");
});
var p4 = new Promise(function(resolve, reject) {
    setTimeout(reject, 500, "four");
});

Promise.race([p3, p4]).then(function(value) {
  console.log(value); 
}, function(reason) {
});

var p5 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 500, "five");
});
var p6 = new Promise(function(resolve, reject) {
    setTimeout(reject, 100, "six");
});

Promise.race([p5, p6]).then(function(value) {
  // 未被调用
}, function(reason) {
  console.log(reason); 
});

Promise.any() 返回第一个成功的promise结果

Promise.any() 接收一个由 Promise 所组成的可迭代对象,该方法会返回一个新的 promise,一旦可迭代对象内的任意一个 promise 变成了兑现状态,那么由该方法所返回的 promise 就会变成兑现状态,并且它的兑现值就是可迭代对象内的首先兑现的 promise 的兑现值。如果可迭代对象内的 promise 最终都没有兑现(即所有 promise 都被拒绝了),那么该方法所返回的 promise 就会变成拒绝状态,并且它的拒因会是一个 AggregateError 实例,这是 Error 的子类,用于把单一的错误集合在一起。

该方法用于获取首个兑现的 promise 的值。只要有一个 promise 兑现了,那么此方法就会提前结束,而不会继续等待其他的 promise 全部敲定。

不像 Promise.all() 会返回一组兑现值那样,我们只能得到一个兑现值(假设至少有一个 promise 兑现)。当我们只需要一个 promise 兑现,而不关心是哪一个兑现时此方法很有用的。

同时,也不像 Promise.race() 总是返回第一个敲定值(兑现或拒绝)那样,这个方法返回的是第一个兑现的值。这个方法将会忽略掉所有的被拒绝的 promise,直到第一个 promise 兑现。

const pErr = new Promise((resolve, reject) => {
  reject("总是失败");
});

const pSlow = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, "最终完成");
});

const pFast = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, "很快完成");
});

Promise.any([pErr, pSlow, pFast]).then((value) => {
  console.log(value);
})

特殊情况

1.then里面不传回调

如果该参数不是函数,则会在内部被替换为 (x) => x,即原样返回 promise 最终结果的函数

2.promise不能等待自己

   const aaa = new Promise((res, rej) => {
        res(111)
    })

    const bbb = aaa.then(res => {
        return bbb
    })

3.then的执行函数返回的值是函数或者对象

返回的对象里面含有then方法,then方法里面必须含有resovle,reject函数

练习题

const promise = new Promise((resolve, reject) => {
  console.log(1)
  resolve()
  console.log(2)
})
promise.then(() => {
  console.log(3)
})
console.log(4)
let p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('success')
  }, 1000)
})
let p2 = p1.then(() => {
  throw new Error('error!!!')
})
console.log('promise1', p1)
console.log('promise2', p2)
setTimeout(() => {
  console.log('promise1', p1)
  console.log('promise2', p2)
}, 2000)
Promise.resolve(1)
  .then((res) => {
    console.log(res)
    return 2
  })
  .catch((err) => {
    return 3
  })
  .then((res) => {
    console.log(res)
  })
Promise.resolve()
  .then(() => {
    return new Error('error!!!')
  })
  .then((res) => {
    console.log('then: ', res)
  })
  .catch((err) => {
    console.log('catch: ', err)
  })
const first = () => (new Promise((resolve, reject) => {
    console.log(3);
    let p = new Promise((resolve, reject) => {
        console.log(7);
        setTimeout(() => {
            console.log(5);
            resolve(6);
        }, 0)
        resolve(1);
    });
    resolve(2);
    p.then((arg) => {
        console.log(arg);
    });

}));

first().then((arg) => {
    console.log(arg);
});
console.log(4);

手写promise

promise 三个状态

   constructor(func) {
            // 定义prmise的两个属性
            this.PromiseState = "pending";
            this.PromiseResult = undefined;
            this.callbacks = [];
            //resolve 做两件事
            // 1.改变promise状态
            // 2.将promise值设置

            // 构造函数接收的一个参数,构造函数接受两个参数, 绑定this是因为函数自调用this指向window
            // 如果函数中出现错误,需要放到rejecte函数打印,rejecte不存在则报错
            try {
                func(this.resolve, this.reject);
            }
            catch (err) {
                // 捕获错误放到reject处理
                this.reject(err);
            }
        }

错误捕获和状态不可变

        resolve = (result) => {
            // 只有状态为pending才能改变,因为promise状态不可变
            if (this.PromiseState === "pending") {
                if (result instanceof YQPromise || typeof result.then === 'function') {
                    resolvePromise(result, null, this.resolve, this.reject);
                } else {

                    this.PromiseState = "fulfilled";
                    this.PromiseResult = result;
                }
                // this.PromiseState = "fulfilled";
                // this.PromiseResult = result;

                // 异步事件结束之后执行onResolve函数

                this.callbacks.map(callback => {
                    callback.onResolve?.(this.PromiseResult);
                });

            }
        };
     reject = (result) => {
            if (this.PromiseState === "pending") {
                this.PromiseState = "rejected";
                this.PromiseResult = result;
                // 异步事件结束之后执行onReject函数

                this.callbacks.map(callback => {
                    callback.onReject?.(this.PromiseResult);
                });
                // console.error(result);

            }
        };

promise then回调

promise 同步事件处理

promise异步事件处理

then的同步返回值

then的异步返回值

    then(onResolved, onRejected) {
            if (typeof onResolved !== "function") {
                // 拒绝函数不传,我们手动赋值一个函数
                onResolved = (data) => data;
            }
            if (typeof onRejected !== "function") {
                // 拒绝函数不传,我们手动赋值一个函数,并且抛出错误
                onRejected = (err) => {
                    throw err;
                };
            }
            const newPromise = new YQPromise((_resolve, _reject) => {
                // 当有异步任务的时候,状态会是pengding,但是then会直接执行,所以异步结束之后不会有后续onResolve或者onRejected执行
                if (this.PromiseState === "pending") {
                    this.callbacks.push({
                        onResolve: () => {
                            queueMicrotask(() => {
                                try {
                                    let res = onResolved(this.PromiseResult);
                                    resolvePromise(res, newPromise, _resolve, _reject);
                                } catch (error) {
                                    _reject(error)
                                }
                            })

                        },
                        onReject: () => {
                            queueMicrotask(() => {
                                try {
                                    let res = onRejected(this.PromiseResult);
                                    resolvePromise(res, newPromise, _resolve, _reject);
                                } catch (error) {
                                    _reject(error)
                                }
                            })
                        },
                    });
                }
                if (this.PromiseState === "fulfilled") {
                    // 微任务执行函数
                    queueMicrotask(() => {
                        // 得到resolve函数返回的结果
                        try {
                            let res = onResolved(this.PromiseResult);
                            resolvePromise(res, newPromise, _resolve, _reject);
                        } catch (error) {
                            _reject(error)
                        }
                    });
                }
                if (this.PromiseState === "rejected") {
                    queueMicrotask(() => {
                        try {
                            let res = onRejected(this.PromiseResult);
                            resolvePromise(res, newPromise, _resolve, _reject);
                        } catch (error) {
                            _reject(error)
                        }
                    });
                }
            });
            return newPromise;
        }

catch错误捕获then值穿透

    catch(onReject) {
            return this.then(undefined, onReject);
        }

静态方法 resolve reject

        // 静态方法 resolve
        static resolve = (data) => {
            return new YQPromise((_resolve, _reject) => {
                resolvePromise(data, null, _resolve, _reject);
            });
        }
        // 静态方法 reject
        static reject(data) {
            return new YQPromise((resolve, reject) => {
                reject(data);
            });
        }

静态方法 all allsettled race any

       /**
         * 
         * @params 
         *  @params 迭代为空 返回同步为空
         * 如果传入的参数不包含任何 promise,则返回一个异步完成Promise。
         * 可迭代的promise,全部成功则成功,一个失败就失败
         */
        static all = (iterable) => {
            let promiseArr = [];
            const newPromiseArr = []
            let count = 0;
            try {
                promiseArr = [...iterable];
            } catch (error) {
                return YQPromise.reject(error)
            }

            if (promiseArr.length === 0) return YQPromise.resolve([]);


            return new YQPromise((_resolve, _reject) => {
                for (let key in promiseArr) {
                    YQPromise.resolve(promiseArr[key]).then(r => {
                        newPromiseArr[key] = r;
                        count++;
                        if (count === promiseArr.length) {
                            _resolve(newPromiseArr)
                        }
                    }, e => {
                        _reject(e)
                    })
                }
            })


        }

        /*
         * @params 迭代为空 返回同步为空
         * 返回所有结果
         */
        static allSettled = (iterable) => {
            let promiseArr = [];
            const newPromiseArr = []
            let count = 0;
            try {
                promiseArr = [...iterable];
            } catch (error) {
                return YQPromise.reject(error)
            }
            if (promiseArr.length === 0) return YQPromise.resolve([]);
            return new YQPromise(_resolve => {
                for (let key in promiseArr) {
                    YQPromise.resolve(promiseArr[key]).then(r => {
                        newPromiseArr[key] = {
                            status: 'fulfilled',
                            value: r
                        }
                    }, e => {
                        newPromiseArr[key] = {
                            status: 'rejected',
                            reason: e
                        }
                    }).finally(() => {
                        count++;
                        if (count === promiseArr.length) {
                            _resolve(newPromiseArr)
                        }
                    })
                }
            })

        }

        /**
         * 
         * @params 迭代为空 则一直等待
         * 结果为第一个状态改变的
         */
        static race = (iterable) => {
            let promiseArr = [];
            try {
                promiseArr = [...iterable];
            } catch (error) {
                return YQPromise.reject(error)
            }
            return new YQPromise((_resolve, _reject) => {
                for (let key in promiseArr) {
                    YQPromise.resolve(promiseArr[key]).then(r => {
                        _resolve(r);
                    }, e => {
                        _reject(e)
                    })
                }
            })



        }

        /**
         * @params 迭代为空 则失败
         * 第一个成功的,全部失败则拒绝
         */
        static any = (iterable) => {
            let promiseArr = [];
            let count = 0;
            try {
                promiseArr = [...iterable];
            } catch (error) {
                return YQPromise.reject(error)
            }
            if (promiseArr.length === 0) {
                console.error("All promises were rejected")
                return YQPromise.reject("All promises were rejected")
            }
            return new YQPromise((_resolve, _reject) => {
                for (let key in promiseArr) {
                    YQPromise.resolve(promiseArr[key]).then(r => {
                        _resolve(r);
                    }, () => {
                        count++;
                        if (count === promiseArr.length) {
                            console.error("All promises were rejected")
                            _reject("All promises were rejected")
                        }

                    })
                }
            })

        }

全部代码

(function (_window, fn) {
    if (typeof module === 'object') {
        module.exports = fn();
    } else {
        _window['Promise'] = fn()
    }


})(this, () => {


    const resolvePromise = (x, newPromise, resolve, reject) => {
        if (x === newPromise) {
            console.error("Chaining cycle detected for promise #<Promise>");
            reject(new TypeError(" Chaining cycle detected for promise #<Promise>"))

        }

        if (x && (typeof x === 'object' || typeof x === 'function')) {
            let called = false;

            try {
                let then = x.then
                if (typeof then === 'function') {
                    then.call(x, r => {
                        if (called) return;
                        called = true;
                        resolvePromise(r, newPromise, resolve, reject);
                    }, e => {
                        if (called) return;
                        called = true;
                        reject(e)
                    })

                } else {
                    if (called) return;
                    called = true;
                    resolve(x)
                }
                
            } catch (error) {
                if (called) return;
                called = true;
                reject(error)
            }
        } else {
            resolve(x)
        }
    }




    class YQPromise {
        constructor(func) {
            this.PromiseState = 'pending';
            this.PromiseResult = undefined;
            this.callbacks = [];
            try {
                func(this.resolve, this.reject)
            } catch (e) {
                // console.error(e);
                this.reject(e)
            }

        }


        resolve = (result) => {
            if (this.PromiseState !== 'pending') return;
            
            if (result instanceof YQPromise || typeof result.then === 'function') {
                resolvePromise(result, {}, this.resolve, this.reject);
            } else {

                this.PromiseState = "fulfilled";
                this.PromiseResult = result;
            }
  

            // this.PromiseState = 'fulfilled';
            // this.PromiseResult = result;

            this.callbacks.map(callback => {
                callback.onfulfilled(this.PromiseResult)
            })
        }


        reject = (reason) => {
            if (this.PromiseState !== 'pending') return;
            this.PromiseState = 'rejected';
            this.PromiseResult = reason;

            this.callbacks.map(callback => {
                callback.onrejected(this.PromiseResult)
            })
        }


        then(onfulfilled, onrejected) {

            if (typeof onfulfilled !== 'function') {
                onfulfilled = data => data;
            }

            if (typeof onrejected !== 'function') {
                onrejected = err => {
                    throw err;
                }
            }



            const newPromise = new YQPromise((_resolve, _reject) => {
                if (this.PromiseState === 'pending') {
                    this.callbacks.push({
                        onfulfilled: () => {
                            queueMicrotask(() => {
                                try {
                                    let x = onfulfilled(this.PromiseResult);
                                    resolvePromise(x, newPromise, _resolve, _reject);
                                } catch (e) {
                                    _reject(e)
                                }
                            })

                        },
                        onrejected: () => {
                            queueMicrotask(() => {
                                try {
                                    let x = onrejected(this.PromiseResult);
                                    resolvePromise(x, newPromise, _resolve, _reject);
                                } catch (e) {
                                    _reject(e)
                                }
                            })

                        }
                    })
                }

                if (this.PromiseState === 'fulfilled') {
                    queueMicrotask(() => {
                        try {
                            let x = onfulfilled(this.PromiseResult);
                            resolvePromise(x, newPromise, _resolve, _reject);
                        } catch (e) {
                            _reject(e)
                        }
                    })

                }

                if (this.PromiseState === 'rejected') {
                    queueMicrotask(() => {
                        try {
                            let x = onrejected(this.PromiseResult);
                            resolvePromise(x, newPromise, _resolve, _reject);
                        } catch (e) {
                            _reject(e)
                        }
                    })

                }
            })

            return newPromise

        }

        catch = (cb) => {
            return this.then(undefined, cb)
        }


        finally(cb) {
            return this.then(res => {
                return YQPromise.resolve(cb()).then(() => res)
            }, err => {
                return YQPromise.resolve(cb()).then(() => {
                    throw err
                })
            })
        }

        static resolve(value) {
            return new YQPromise((_resolve, _reject) => {
                resolvePromise(value, {}, _resolve, _reject);
            })
        }

        static reject(reason) {
            return new YQPromise((_resolve, _reject) => {
                _reject(reason)
            })
        }

        /**
         * 
         * @params 
         *  @params 迭代为空 返回同步为空
         * 如果传入的参数不包含任何 promise,则返回一个异步完成Promise。
         * 可迭代的promise,全部成功则成功,一个失败就失败
         */
        static all = (iterable) => {
            let promiseArr = [];
            const newPromiseArr = []
            let count = 0;
            try {
                promiseArr = [...iterable];
            } catch (error) {
                return YQPromise.reject(error)
            }

            if (promiseArr.length === 0) return YQPromise.resolve([]);


            return new YQPromise((_resolve, _reject) => {
                for (let key in promiseArr) {
                    YQPromise.resolve(promiseArr[key]).then(r => {
                        newPromiseArr[key] = r;
                        count++;
                        if (count === promiseArr.length) {
                            _resolve(newPromiseArr)
                        }
                    }, e => {
                        _reject(e)
                    })
                }
            })


        }

        /*
         * @params 迭代为空 返回同步为空
         * 返回所有结果
         */
        static allSettled = (iterable) => {
            let promiseArr = [];
            const newPromiseArr = []
            let count = 0;
            try {
                promiseArr = [...iterable];
            } catch (error) {
                return YQPromise.reject(error)
            }
            if (promiseArr.length === 0) return YQPromise.resolve([]);
            return new YQPromise(_resolve => {
                for (let key in promiseArr) {
                    YQPromise.resolve(promiseArr[key]).then(r => {
                        newPromiseArr[key] = {
                            status: 'fulfilled',
                            value: r
                        }
                    }, e => {
                        newPromiseArr[key] = {
                            status: 'rejected',
                            reason: e
                        }
                    }).finally(() => {
                        count++;
                        if (count === promiseArr.length) {
                            _resolve(newPromiseArr)
                        }
                    })
                }
            })

        }

        /**
         * 
         * @params 迭代为空 则一直等待
         * 结果为第一个状态改变的
         */
        static race = (iterable) => {
            let promiseArr = [];
            try {
                promiseArr = [...iterable];
            } catch (error) {
                return YQPromise.reject(error)
            }
            return new YQPromise((_resolve, _reject) => {
                for (let key in promiseArr) {
                    YQPromise.resolve(promiseArr[key]).then(r => {
                        _resolve(r);
                    }, e => {
                        _reject(e)
                    })
                }
            })
        }

        /**
         * @params 迭代为空 则失败
         * 第一个成功的,全部失败则拒绝
         */
        static any = (iterable) => {
            let promiseArr = [];
            let count = 0;
            try {
                promiseArr = [...iterable];
            } catch (error) {
                return YQPromise.reject(error)
            }
            if (promiseArr.length === 0) {
                console.error("All promises were rejected")
                return YQPromise.reject("All promises were rejected")
            }
            return new YQPromise((_resolve, _reject) => {
                for (let key in promiseArr) {
                    YQPromise.resolve(promiseArr[key]).then(r => {
                        _resolve(r);
                    }, () => {
                        count++;
                        if (count === promiseArr.length) {
                            console.error("All promises were rejected")
                            _reject("All promises were rejected")
                        }

                    })
                }
            })

        }
    }
    return YQPromise;
})

测试用例

npm i promises-aplus-tests

test.js

const YQPromise = require("./promise");

const resolved = v => YQPromise.resolve(v);
const rejected = v => YQPromise.reject(v);

const deferred = () => {
    let resolve;
    let reject;
    const promise = new YQPromise((res, rej) => {
        resolve = res;
        reject = rej
    });
    return {
        promise,
        resolve,
        reject
    }
}
module.exports = {
    deferred,
    resolved,
    rejected,
}

package.json

{
  "scripts": {
    "test": "promises-aplus-tests ./test.js"
  },
  "dependencies": {
    "promises-aplus-tests": "^2.1.2"
  }
}

2.3.3扩充

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pmceHGFc-1663835703491)(精通promise.assets/image-20220922145836838.png)]

Promise是一种异步编程的解决方案,可以避免回调地狱的问题。下面是使用class手写一个Promise的示例代码: ``` class MyPromise { constructor(executor) { this.status = 'pending'; // Promise的状态 this.value = undefined; // Promise的结果 this.reason = undefined; // Promise的错误信息 const resolve = (value) => { if (this.status === 'pending') { this.status = 'fulfilled'; this.value = value; } }; const reject = (reason) => { if (this.status === 'pending') { this.status = 'rejected'; this.reason = reason; } }; try { executor(resolve, reject); } catch (error) { reject(error); } } then(onFulfilled, onRejected) { onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => value; onRejected = typeof onRejected === 'function' ? onRejected : (reason) => { throw reason }; const promise2 = new MyPromise((resolve, reject) => { if (this.status === 'fulfilled') { setTimeout(() => { try { const x = onFulfilled(this.value); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, ); } else if (this.status === 'rejected') { setTimeout(() => { try { const x = onRejected(this.reason); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, ); } else { this.onFulfilledCallbacks.push(() => { setTimeout(() => { try { const x = onFulfilled(this.value); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, ); }); this.onRejectedCallbacks.push(() => { setTimeout(() => { try { const x = onRejected(this.reason); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, ); }); } }); return promise2; } catch(onRejected) { return this.then(null, onRejected); } } function resolvePromise(promise2, x, resolve, reject) { if (promise2 === x) { reject(new TypeError('Chaining cycle detected for promise')); } let called = false; if (x !== null && (typeof x === 'object' || typeof x === 'function')) { try { const then = x.then; if (typeof then === 'function') { then.call(x, (y) => { if (called) return; called = true; resolvePromise(promise2, y, resolve, reject); }, (r) => { if (called) return; called = true; reject(r); }); } else { resolve(x); } } catch (error) { if (called) return; called = true; reject(error); } } else { resolve(x); } } ``` 以上是一个简单的Promise实现,其中包含了Promise的基本功能,如状态管理、then方法、catch方法等。需要注意的是,Promise的实现并不是一件简单的事情,需要考虑到各种边界情况,才能保证其正确性稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值