手写 Promise:从零开始实现 JavaScript Promise 对象
手写 Promise:从零开始实现 JavaScript Promise 对象
本文将带你一步步从零开始实现 JavaScript Promise 对象,深入理解 Promise 的运作机制。
1. Promise 的构造函数
首先,我们需要创建 Promise 的构造函数,它接收一个参数:执行函数 (executor function)。执行函数有两个参数,分别是 resolve 和 reject 函数,它们用于改变 Promise 的状态。
function MyPromise(executor) {
this.status = 'pending';
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.status === 'pending') {
this.status = 'resolved';
this.value = value;
this.onResolvedCallbacks.forEach((fn) => fn());
}
};
const reject = (reason) => {
if (this.status === 'pending') {
this.status = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach((fn) => fn());
}
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
2. 实现 Promise 的核心功能
接下来,我们需要实现 Promise 的核心功能,包括:
- 三种状态: pending (等待), resolved (成功), rejected (失败);初始状态为 pending,状态一旦改变便不可逆转。
- then 函数: 接收两个参数:onResolved 和 onRejected,分别对应成功和失败时的回调函数。
- resolve 和 reject 函数: 分别用于将 Promise 的状态更改为 resolved 和 rejected。
MyPromise.prototype.then = function (onResolved, onRejected) {
onResolved = typeof onResolved === 'function' ? onResolved : (value) => value;
onRejected = typeof onRejected === 'function' ? onRejected : (reason) => { throw reason; };
const promise2 = new MyPromise((resolve, reject) => {
if (this.status === 'resolved') {
setTimeout(() => {
try {
const x = onResolved(this.value);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
}
if (this.status === 'rejected') {
setTimeout(() => {
try {
const x = onRejected(this.reason);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
}
if (this.status === 'pending') {
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onResolved(this.value);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
}
});
return promise2;
};
MyPromise.prototype.resolvePromise = function (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;
this.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);
}
};
MyPromise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected);
};
MyPromise.resolve = function (value) {
return new MyPromise((resolve) => {
resolve(value);
});
};
MyPromise.reject = function (reason) {
return new MyPromise((resolve, reject) => {
reject(reason);
});
};
MyPromise.all = function (promises) {
return new MyPromise((resolve, reject) => {
const result = [];
let count = 0;
for (let i = 0; i < promises.length; i++) {
promises[i].then(
(value) => {
result[i] = value;
count++;
if (count === promises.length) {
resolve(result);
}
},
(reason) => {
reject(reason);
}
);
}
});
};
MyPromise.race = function (promises) {
return new MyPromise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(
(value) => {
resolve(value);
},
(reason) => {
reject(reason);
}
);
}
});
};
3. 测试代码
最后,我们编写一段测试代码来验证我们的自定义 Promise 对象。
const promise = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('success');
}, 1000);
});
promise
.then(
(value) => {
console.log(value);
return 'hello';
},
(reason) => {
console.log(reason);
}
)
.then(
(value) => {
console.log(value);
},
(reason) => {
console.log(reason);
}
);
通过以上步骤,我们就成功地实现了自定义 Promise 对象,并且验证了它的功能。
注意: 为了简单起见,以上代码省略了一些 Promise 的特性,比如 Promise.allSettled、Promise.any 等。你可以在此基础上进一步扩展和完善你的 Promise 实现。
原文地址: https://www.cveoy.top/t/topic/nv9l 著作权归作者所有。请勿转载和采集!