写一个自己的 Promise,从零开始
2023-10-03 05:35:30
对于 JavaScript 开发人员来说,Promise 是一个非常有用的工具,它可以让你处理异步操作。然而,编写自己的 Promise 可能会让人望而生畏。在这篇文章中,我将通过测试先行的方式,手把手地教你如何从零开始编写自己的 Promise。
测试先行
测试先行是一种编写代码的技巧,它涉及编写测试,然后根据测试编写代码。这有助于确保你的代码从一开始就按照预期工作。对于编写 Promise 来说,这种方法特别有用,因为它可以帮助你隔离和测试 Promise 的各个方面。
编写 Promise 的步骤
让我们按照以下步骤来编写一个 Promise:
1. 编写测试
首先,让我们编写一个简单的测试,来测试 Promise 是否可以正常解析。
it('should resolve', () => {
const promise = new Promise((resolve) => {
setTimeout(() => {
resolve('成功!');
}, 1000);
});
return expect(promise).resolves.toBe('成功!');
});
2. 实现 Promise
接下来,让我们实现一个最简单的 Promise,它只包含 resolve
方法。
class Promise {
constructor(executor) {
this.executor = executor;
this.state = 'pending';
this.value = undefined;
}
resolve(value) {
this.state = 'fulfilled';
this.value = value;
}
}
3. 添加 then
方法
then
方法用于处理 Promise 的结果。让我们添加一个 then
方法到我们的 Promise 类:
then(onFulfilled) {
return new Promise((resolve) => {
this.executor((value) => {
const result = onFulfilled(value);
resolve(result);
});
});
}
4. 处理 rejected Promise
Promise 还可以被 rejected,这意味着操作失败。让我们添加一个 catch
方法来处理这种情况:
catch(onRejected) {
return this.then(undefined, onRejected);
}
5. 添加 finally
方法
finally
方法始终在 Promise 完成后执行,无论 Promise 是 resolved 还是 rejected。让我们添加一个 finally
方法:
finally(onFinally) {
return this.then(onFinally, onFinally);
}
完整代码
以下是完整 Promise 实现的代码:
class Promise {
constructor(executor) {
this.executor = executor;
this.state = 'pending';
this.value = undefined;
}
resolve(value) {
this.state = 'fulfilled';
this.value = value;
}
then(onFulfilled) {
return new Promise((resolve) => {
this.executor((value) => {
const result = onFulfilled(value);
resolve(result);
});
});
}
catch(onRejected) {
return this.then(undefined, onRejected);
}
finally(onFinally) {
return this.then(onFinally, onFinally);
}
}
使用 Promise
现在我们已经实现了自己的 Promise,让我们看看如何使用它:
const promise = new Promise((resolve) => {
setTimeout(() => {
resolve('成功!');
}, 1000);
});
promise.then((value) => {
console.log(value); // 输出:成功!
});
总结
在本文中,我们通过测试先行的方式一步一步地实现了自己的 Promise。我们涵盖了 Promise 的基本功能,包括 resolve
、then
、catch
和 finally
方法。你现在应该对 Promise 的内部工作原理有了更深入的理解,并且可以自信地编写自己的 Promise 来处理异步操作。