gpt4 book ai didi

javascript - 理解 JS Promises

转载 作者:可可西里 更新时间:2023-11-01 01:24:11 25 4
gpt4 key购买 nike

我想更深入地了解 Promises 的内部工作原理。因此我有一些示例代码:

var p1 = new Promise(
function(resolve, reject) {
window.setTimeout(
function() {
resolve('res called')
}, 2000);
});


var p2 = new Promise(
function(resolve, reject) {
window.setTimeout(
function() {
resolve('res called')
}, 2000);
});


function chainPromises() {
return p1.then(function(val) {
console.log("p1");
return p2.then(function(val) {
console.log("p2");
return val;
});
});
}

chainPromises().then(function(val) {
console.log(val);
});

这里是link执行此代码。

正如您所预料的那样,首先解析 p1,然后解析 p2,最后 final then 打印解析值。

但是 API 引用声明如下:

"then" returns a new promise equivalent to the value you return from onFulfilled/onRejected after being passed through Promise.resolve

所以知道“then”函数执行的确切时间会很有趣吗?因为代码中最后的“then”链接到chainPromises(),我首先想到的是它会在函数 chainPromises() 返回一些东西(在本例中是另一个 promise )之后执行。

如果是这种情况,最终“then”函数的“val”将是返回的 promise 。但是相反,最后的“then”会等到返回的第一个“then”中的所有 promise 都已解决。这绝对是有道理的,因为通过这种方式,可以堆叠“then”函数,但是由于 API 规范,我真的不明白这是如何完成的。并没有真正涵盖“then”返回的内容以及“then”函数何时执行。

或者换句话说,为什么最终的“then”函数要等到 chainPromises() 函数内的所有 Promise 都已解析,而不是像 API 文档所说的那样只等待第一个返回的对象。

我希望我能说清楚我的意思.. :)

最佳答案

关于 Promise 解析

您在这里看到的事情称为递归thenable resolution。 Promises/A+ 规范中的 promise 解析过程包含以下子句:

onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x)

ES6 promise 规范(promises unwrapping)包含类似的条款。

这要求当 resolve 操作发生时:在 promise 构造函数中,通过调用 Promise.resolve 或在您的情况下在 then 链接一个 promise 实现必须如果它是一个 promise,则递归地展开返回值。

实践

这意味着如果 onFulfilled(then)返回一个值,尝试自己“解决”promise 值,从而递归地等待整个链。

这意味着:

promiseReturning().then(function(){
alert(1);
return foo(); // foo returns a promise
}).then(function(){
alert(2); // will only run after the ENTIRE chain of `foo` resolved
// if foo OR ANY PART OF THE CHAIN rejects and it is not handled this
// will not run
});

例如:

promiseReturning().then(function(){
alert(1);
return Promise.resolve().then(function(){ throw Error(); });
}).then(function(){
alert("This will never run");
});

还有:

promiseReturning().then(function(){
alert(1);
return Promise.resolve().then(function(){ return delay(2000); });
}).then(function(){
alert("This will only run after 2000 ms");
});

这是个好主意吗?

在 promises 规范过程中,讨论了不表现出这种行为的第二种链方法,但决定反对(在 Chrome 中仍然可用,但很快就会被删除),这一直是 promises 规范过程中争论不休的话题。您可以阅读整个辩论 in this esdiscuss thread . 此行为是出于实用原因,因此您不必手动执行此操作。

在其他语言中

值得一提的是,其他语言并没有这样做,Scala 中的 futures 和 C# 中的 tasks 都没有这个属性。例如,在 C# 中,您必须对任务调用 Task.Unwrap 才能等待其链解析。

关于javascript - 理解 JS Promises,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27638060/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com