javascript - 调用 then 函数时如何触发回调?
问题描述
我找到了一个自定义的 js promise 实现并试图理解它,但我无法弄清楚回调是如何执行或触发的,因为 promise 的定义被立即调用但我们只是在 then 实现中推入回调数组
https://playcode.io/364624?tabs=script.js,preview,console
function myPromise(definitionFunction){
this.thenCallbacks = [];
this.status = 'pending';
this.value = undefined;
definitionFunction(resolver.bind(this),rejector.bind(this));
function resolver(value)
{
this.status = 'resolved';
this.value = value;
this.thenCallbacks.forEach(function(func){
console.log(func);
this.value = func(this.value);
},this);
}
function rejector(value)
{
}
}
myPromise.prototype.then = function(successCallback,errorCallback){
this.thenCallbacks.push(successCallback);
return this;
}
var test = new myPromise(function(resolve,reject){
var xhttp = new XMLHttpRequest();
var url = "https://jsonmock.hackerrank.com/api/stocks/search?page="+1;
xhttp.open("GET",url , true);
xhttp.onload = function() {
if (this.readyState == 4 && this.status == 200) {
resolve(this.responseText);
}
else
{
reject({
status: this.status,
statusText: xhttp.statusText
})
}
};
xhttp.onerror = function() {
reject({
status: this.status,
statusText: xhr.statusText
});
}
xhttp.send();
});
test.then((response)=>'kiran').then((resp)=>{return{name:'kiran'}}).then((resp)=>console.log(resp));
有人可以清除这个吗
解决方案
首先,这是一个特别糟糕的 Promise 实现,因为它会做各种错误的事情:
- 在当前执行线程完成后,它不会异步解决,这可能会导致时间不一致问题。
- 它不支持正确链接
.then().then()
where.then()
返回一个新的 Promise,因此第二个.then()
只有在第一个 Promise 解决后才调用它的处理程序。 - 它不支持正确的链接,其中
.then()
回调处理程序可以返回将插入到链中的承诺 - 它不会调用
.then()
在 promise 已经解决后添加的处理程序。 - 它不会锁定承诺的状态,因此无法更改。
- 它不会在执行程序
.then()
或.catch()
处理程序中捕获同步异常并将它们转换为被拒绝的承诺。
为了获得更好的实现,我建议您查阅以下代码:https ://www.promisejs.org/implementing/这显然是从这个stackoverflow 答案开始的,因为这将使您更好地了解实现承诺所涉及的内容.
我无法弄清楚回调是如何执行或触发的,因为 promise 的定义被立即调用,但我们只是在实现中推入回调数组
什么.then()
是注册一个回调(保存它),以便将来可以调用它。因此,它很自然地会向一个数组添加一个回调,然后该数组中的回调可以在未来的某个时间执行(比如当 promise 实现时)。
在这个实现definitionFunction()
中是承诺执行者。它是传递给new Promise(fn)
构造函数的回调,它应该被立即调用。
.then()
然后将回调存储在一个数组中。
然后,稍后当resolver()
调用来自执行程序的函数时,它将迭代该数组this.thenCallbacks.forEach()
并调用数组中的每个函数。
但是,这个实现在很多方面都不能正常工作。如果resolver()
立即调用,则.thenCallbacks
数组将为空,因为.then()
尚未在 promise 上调用,然后在.then()
稍后的某个时间在已解决的 promise 上调用时,它不会调用回调。
正如我在评论中所说,我不想再花时间讨论这种有缺陷的承诺实现是如何工作的。我试图回答你的直接问题,并引导你走向一个更好、更准确、更完整的 Promise 实现,你可以继续学习。这个有各种各样的问题,所以在我看来,不值得花更多时间了解它是如何工作的。
您还可以花一些时间阅读Promises/A+ 规范,这实际上并不复杂,难以阅读或理解。
推荐阅读
- sql - 如何在只读源表和更新表之间共享 id
- php - 将使用 fopen 创建的文件上传到 AWS S3 存储桶
- git - 如何将分支合并到 master 后面的 master 中?
- reactjs - 如何在 setState() 中使用三元表达式?
- python-3.x - 在 pandas 中使用 groupby.first() 替换空值
- linux - 如何编写一个 shell 脚本来传递 ssh-add 私钥的密码?
- vim - 无root权限安装vim
- android - 如何开发跨平台应用程序库
- sql - Oracle SQL 检查日期字段是否在一定范围内
- c++ - 如何实现 std::is_nothrow_constructible