手写实现Promise
- promise有三种状态,即pending(等待)、fulfilled(成功)、rejected(拒绝)。
- 首先实现Promise
- 以下代码的实现都是在B站学习视频中记录的笔记
代码
// 基本结构
function myPromise(executor) {
let self = this;
self.status = 'pending' //状态
self.value = null; // 成功的结果
self.reason = null; //失败的原因
// 为了解决异步 存放的容器
self.onFulFilledCallbacks = [];
self.onRejectedCallbacks = [];
function resolve(value) {
// 状态判断
if (self.status === 'pending') {
self.value = value; // 保存成功结果
self.status = 'fulfilled';
self.onFulFilledCallbacks.forEach(item => {
item(value)
});
}
}
function reject(reason) {
self.value = reason; // 失败的原因
self.status = 'rejected';
self.onRejectedCallbacks.forEach(item => {
item(reason)
});
}
// 实例化之后,必须要立即执行一遍
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
// .then()
myPromise.prototype.then = function (onFulFilled, onRejected) {
onFulFilled = typeof onFulFilled === 'function' ? onFulFilled : function (data) {
resolve(data)
}
onRejected = typeof onRejected === 'function' ? onRejected : function (err) {
throw err
}
let self = this;
if (self.status === 'pending') {
self.onFulFilledCallbacks.push(onFulFilled);
self.onRejectedCallbacks.push(onRejected);
}
if (self.status == 'fulfilled') {
onFulFilled(this.value)
} else if (self.status == 'rejected') {
onRejected(this.reason)
}
}
- Promise.all实现过程
代码
//promise.all手写实现
function promiseAll(promiseArray) {
return new Promise((resolve, reject) => {
//如果传入的不是一个数组,就直接返回错误
if(!Array.isArray(promiseArray)) {
return reject(new Error("传入的参数不是一个数组!"))
}
const res = [];
const promiseNums = promiseArray.length;
/*
* 对于传入的每一个promise对象,不确定其哪个先执行完毕,所以不能直接判断数组下标
*/
//由于js数组的特殊性,必须要这个计数
let counter = 0;
for(let i = 0;i < promiseNums;i++) {
Promise.resolve(promiseArray[i]).then(value => {
//执行完一个promise就将counter加1,直到所有的promise执行完毕
counter++;
//存储结果
res[i] = value;
if(counter === promiseNums) {
resolve(res);
}
}).catch(e => {
reject(e);
})
}
})
}
总结
promise是JavaScript高级知识,在实际开发中经常会用到,在项目中会结合async、await使用(这个是异步调用的语法糖,让异步代码看起来就像是同步的,更容易理解,也更容易阅读)。在开发中,向服务器请求数据时,如果后端返回的是promise对象,就可以使用async、await。
虽然用async、await很方便,但是也要认真学习promise是如何实现的。
每天进步一点点,加油!!!