javascript - Promise 的一个极其简单的实现是如何工作的
问题描述
我正在阅读这篇关于promise
. 为此,作者展示了一个promise
正常工作的简化实现。
代码如下:
class PromiseSimple {
constructor(executionFunction) {
this.promiseChain = [];
this.handleError = () => {};
this.onResolve = this.onResolve.bind(this);
this.onReject = this.onReject.bind(this);
executionFunction(this.onResolve, this.onReject);
}
then(onResolve) {
this.promiseChain.push(onResolve);
return this;
}
catch(handleError) {
this.handleError = handleError;
return this;
}
onResolve(value) {
let storedValue = value;
try {
this.promiseChain.forEach((nextFunction) => {
storedValue = nextFunction(storedValue);
});
} catch (error) {
this.promiseChain = [];
this.onReject(error);
}
}
onReject(error) {
this.handleError(error);
}
}
它被这样称呼,就像一个普通的promise
:
// Assume this is your AJAX library. Almost all newer
// ones return a Promise Object
const makeApiCall = () => {
return new PromiseSimple((resolve, reject) => {
// Use a timeout to simulate the network delay waiting for the response.
// This is THE reason you use a promise. It waits for the API to respond
// and after received, it executes code in the `then()` blocks in order.
// If it executed is immediately, there would be no data.
setTimeout(() => {
const apiResponse = fakeApiBackend();
if (apiResponse.statusCode >= 400) {
reject(apiResponse);
} else {
resolve(apiResponse.data);
}
}, 5000);
});
};
我很难掌握以下内容:
为什么行
6
和7
类PromiseSimple
存在?我试图理解绑定this.onResolve
到this
. 它不是已经绑定到适当的this
上下文了吗?我不明白为什么这个实现不会阻塞主线程。在
PromiseSimple
类中的任何地方都没有将工作卸载到另一个线程或任何类似的东西上。但可以肯定的是,如果我console.log(...)
在程序的最后放置一个语句,该console.log(...)
语句将作为我期望的第一件事被打印出来,就像一个常规的promise
. 我想它会被暂停,直到假makeApiCall
函数完成,因为这不是一个真正的实现promise
。
我想掌握这一点,但我只是不明白这个迷你实现如何允许promise
我们习惯的正确行为。任何帮助是极大的赞赏。
更新
已经提出了将其复制的建议,但我想详细说明为什么它们不一样。重复的问题是关于为什么需要异步调用的更高层次的理论。我了解它们的用途、重要性以及实施它们的各种方式。我希望了解它们的工作原理。
解决方案
onResolve
并且onReject
必须绑定以防止executionFunction
将它们与另一个上下文或没有任何上下文一起应用。(如果出于任何原因您调用resolve
或reject
使用其他上下文,它必须绑定到PromiseSimple
,否则this
将引用其他内容,或者如果没有上下文则不会引用任何内容)。
onResolve
这是一个如果您不绑定或将不起作用的示例onReject
:
const makeApiCall = () => {
return new PromiseSimple((resolve, reject) => {
Promise.resolve().then(resolve); // Using native promise here : resolve is called without context and won't work if not bound
});
}
- 这个实现确实阻塞了主线程,但你可能看不到它,因为你使用了一个 setTimeout 来延迟事件循环中的执行。真正的 Promise 实现会延迟您在事件循环中定义
then
或catch
回调为微任务的任务。(有一篇关于浏览器事件循环的非常有趣的文章)。
希望这可以帮助,
推荐阅读
- sql-server - 不工作的存储过程
- android - 即使我设置布局宽度匹配父项,RecyclerView 也仅显示半屏
- javascript - 通过 WebAPI + jquery (ASP.NET core) 删除元素
- python - 如何使用空格作为分隔符来获取字符串中的子字符串?
- javascript - 在javascript ajax请求中获取特定的数组键
- laravel - 如何在 phpartisan 服务中自定义 url
- c# - 如何在 WPF MVVM 运行时从文本框值调整图像大小?
- python - 我可以仅使用 flow() 而不是 flow_from_directory 在 Keras 中增加图像和蒙版吗?
- ios - 应用渐变后获取透明 UIButton
- shiny - R Shiny Radiobuttons 几个列表