您的位置:首页 > 文旅 > 旅游 > Promise 工具箱:手写实现静态方法的完全指南

Promise 工具箱:手写实现静态方法的完全指南

2024/10/7 4:34:24 来源:https://blog.csdn.net/weixin_43288600/article/details/141784208  浏览:    关键词:Promise 工具箱:手写实现静态方法的完全指南

前言

 📫 大家好,我是南木元元,热爱技术和分享,欢迎大家交流,一起学习进步!

 🍅 个人主页:南木元元


Promise有很多静态方法,本文就来分享下如何实现这些静态方法。

目录

静态方法

实现Promise.resolve和Promise.reject

实现Promise.all

实现Promise.allSettled

实现Promise.race

实现Promise.any

实现finally实例方法

结语


静态方法

静态方法是指直接定义在类上的方法,而不是定义在类实例上的方法。它们可以通过类本身调用,而不需要创建类的实例。静态方法通常用于用于在类级别上操作数据和提供一些实用功能,而不需要实例化对象。比如,可以在 Math 类中定义一些数学计算相关的静态方法。

在上文中,我们已经实现了Promsie中最重要的resolve、reject和then方法,但上文实现的代码是不支持直接使用MyPromise.resolve和MyPromise.reject这种形式的。我们可以在Promise 类上通过static关键字直接定义静态方法,来允许对多个 Promise 对象进行操作或直接创建新的 Promise,而无需实例化一个新的 Promise 对象。

实现Promise.resolve和Promise.reject

MDN上对Promise.resolve()和Promise.reject()的定义:

1.Promise.resolve() 静态方法将给定的值转换为一个 Promise。如果该值本身就是一个 Promise,那么该 Promise 将被返回;如果该值是一个thenable对象,Promise.resolve() 将调用其then() 方法及其两个回调函数;否则,返回的 Promise 将会以该值兑现。

2.Promise.reject() 静态方法返回一个已拒绝(rejected)的Promise  对象,拒绝原因为给定的参数。

class MyPromise {...// resolve 静态方法,返回一个以给定值解析后的Promise对象static resolve (param) {// 1.传参为Promise,直接返回if (param instanceof MyPromise) return param;// 2.直接返回以该值为成功状态的promise对象return new MyPromise(resolve =>  {resolve(param);});}// reject 静态方法,返回一个带有拒绝原因(拒绝原因为给定参数)的Promise对象static reject (reason) {return new MyPromise((resolve, reject) => {reject(reason);});}
}

测试:

MyPromise.resolve().then(() => {console.log(0);//0return MyPromise.resolve(4);
}).then((res) => {console.log(res)//4
})

实现Promise.all

all方法用于将多个Promise实例包装成一个新的Promise实例,只有当所有的Promise实例都成功时,新的Promise实例才会成功。

static all(promises) {return new Promise(function(resolve, reject) {//传入参数为一个空的可迭代对象,直接resolveif (promises.length === 0) {resolve([]);} else {const res = [];let count = 0;for (let i = 0; i < promises.length; i++) {//为什么不直接promise[i].then, 因为promise[i]可能不是一个promise, 也可能是普通值Promise.resolve(promises[i]).then((data) => {res[i] = data;count++;if (count === promises.length) {resolve(res);//如果所有Promise都成功,则返回成功结果数组}}).catch((err) => {reject(err);//如果有一个Promise失败,则返回这个失败结果});}}})
}

测试:

const promise1 = MyPromise.resolve(3);
const promise2 = 42;
const promise3 = new MyPromise((resolve, reject) => {setTimeout(resolve, 100, "foo");
});MyPromise.all([promise1, promise2, promise3]).then((values) => {console.log(values); //[3, 42, "foo"]
});

实现Promise.allSettled

Promise.allSettled跟Promise.all类似, 唯一的不同在于, 其不会进行短路, 也就是说当Promise全部处理完成后我们可以拿到每个Promise的状态,而不管其是否处理成功。

当有多个彼此不依赖的异步任务成功完成时,或者您总是想知道每个Promise的结果时,通常使用它。如果任务相互依赖,或者如果你想立即拒绝其中任何任务Promise.all()方法更合适。

static allSettled(promises) {return new Promise(function(resolve, reject) {//传入参数为一个空的可迭代对象,直接resolveif (promises.length === 0) {resolve([]);} else {const res = [];let count = 0;for (let i = 0; i < promises.length; i++) {//为什么不直接promise[i].then, 因为promise[i]可能不是一个promise, 也可能是普通值Promise.resolve(promises[i]).then((data) => {res[i] = {status: 'fulfilled', value: data};count++;if (count === promises.length) {resolve(res);//如果所有Promise都成功,则返回成功结果数组}}).catch((err) => {//失败的时候,不直接返回,而是也把当前状态保存到数组中,等执行完毕时一起返回该数组res[i] = {status: 'rejected', value: err};count++;if (count === promises.length) {resolve(res);}});}}})
}

测试:

MyPromise.allSettled([MyPromise.resolve(33),new MyPromise((resolve) => setTimeout(() => resolve(66), 0)),99,MyPromise.reject(new Error("an error"))
]).then((values) => {console.log(values);
});

实现Promise.race

race 的实现:只要有一个 promise 执行完,直接 resolve 并停止执行。

static race(promises) {return new Promise(function(resolve, reject) {//传入参数为一个空的可迭代对象,直接resolveif (promises.length === 0) {resolve([]);} else {for (let i = 0; i < promises.length; i++) {//为什么不直接promise[i].then, 因为promise[i]可能不是一个promise, 也可能是普通值Promise.resolve(promises[i]).then((data) => {resolve(data); //返回最快的结果}).catch((err) => {reject(err); //返回最快的结果});}}})
}

测试:

const promise1 = new MyPromise((resolve, reject) => {setTimeout(resolve, 500, 'one');
});
const promise2 = new MyPromise((resolve, reject) => {setTimeout(resolve, 100, 'two');
});
MyPromise.race([promise1, promise2]).then((value) => {console.log(value);	//two
});

 

实现Promise.any

Promise.any() 静态方法会在任意一个传入的 Promise 成功时,返回该成功的结果。如果所有传入的 Promise 都被拒绝(即失败),它会以AggregateError的形式被拒绝,其中包含所有被拒绝的原因。

static any(promises) {return new Promise(function (resolve, reject) {//传入参数为一个空的可迭代对象,直接resolveif (promises.length === 0) {resolve([]);} else {let count = 0;for (let i = 0; i < promises.length; i++) {//为什么不直接promise[i].then, 因为promise[i]可能不是一个promise, 也可能是普通值Promise.resolve(promises[i]).then((data) => {resolve(data); //有一个Promise成功,就返回那个结果}).catch((err) => {count++;if (count === promises.length) {//当所有输入Promise都被拒绝时,会以一个包含拒绝原因数组的AggregateError拒绝,AggregateError对象代表了包装了多个错误对象的单个错误对象reject(new AggregateError('All promises were rejected')); //所有Promise都失败,就报错}});}}});
}

实现finally实例方法

无论Promise是成功还是失败,都会调用finally方法,执行 finally 中传入的函数,并且将值原封不动的往下传,以保证可以继续链式调用。

MyPromise.prototype.finally = function (callback) {// 调用then方法,传入两个相同的处理函数,返回一个新的 Promise 对象(保证链式调用)return this.then(value => {// 创建一个新的Promise实例,确保异步执行callbackreturn MyPromise.resolve(callback()).then(() => value);},reason => {// 创建一个新的Promise实例,确保异步执行callbackreturn MyPromise.resolve(callback()).then(() => { throw reason; });});
}

结语

🔥如果此文对你有帮助的话,欢迎💗关注、👍点赞、⭐收藏、✍️评论,支持一下博主~ 

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com