手动实现Promise对象
Promise 是一种异步编程的解决方案,主要用于解决前端回调地狱问题。它是一个容器,保存着某个未来才会结束的事件(通常是异步操作)的结果。
Promise 有三种状态:pending(初始状态)、fulfilled(成功)和rejected(失败)。初始状态只能变为 fulfilled 或 rejected,且这一过程是不可逆的。当状态发生改变时,会触发相应的回调方法。此外,Promise 支持链式调用,then 和 catch 方法会返回一个新的 Promise 对象,以便进行链式调用。
具体实现步骤如下:
- 定义一个执行器函数
fn,该函数接受两个参数resolve和reject。在实例化 Promise 时,调用执行器fn,传入resolve和reject,并初始化回调事件队列taskList。 - 在调用
then方法时,判断当前状态是否为 pending。如果是,则将then中的成功和失败回调推入任务队列taskList中,并返回一个新的 Promise 实例。 - 通过唯一标识符
id来区分不同的 Promise 实例。 - 当执行器中的
resolve或reject被调用时,根据id执行相应的回调方法。
代码实现如下:
let index = 0;
function MyPromise(fn) {
this.RESOLVE = "fulfilled";
this.PENDING = "pending";
this.REJECT = "rejected";
this.id = index++;
this.state = this.PENDING;
this.taskList = [];
this.finallyCallback = null;
fn(this.resolve.bind(this), this.reject.bind(this));
}
MyPromise.prototype.resolve = function (value) {
this.state = this.RESOLVE;
this.executeCallbacks(value);
};
MyPromise.prototype.reject = function (value) {
this.state = this.REJECT;
this.executeCallbacks(value);
};
MyPromise.prototype.executeCallbacks = function (value) {
let task = this.taskList[this.id];
if (task) {
let result;
if (this.state === this.RESOLVE) {
result = task.onFulfilled(value);
} else if (this.state === this.REJECT) {
result = task.onRejected(value);
}
let nextId = this.id + 1;
if (result instanceof MyPromise) {
result.id = nextId;
result.taskList = this.taskList;
result.finallyCallback = this.finallyCallback;
} else {
this.finallyCallback && this.finallyCallback();
}
}
};
MyPromise.prototype.then = function (onFulfilled, onRejected) {
let obj = { onFulfilled, onRejected };
if (this.state === this.PENDING) {
this.taskList.push(obj);
}
return this;
};
MyPromise.prototype.finally = function (callback) {
this.finallyCallback = callback;
};
调用示例:
var cc = new MyPromise(function (resolve, reject) {
setTimeout(() => {
resolve(2);
}, 200);
});
cc.then(
num => console.log(num, '11'), // 成功回调
err => console.log(err, '22') // 失败回调
);