理解JS承诺 [英] Understanding JS Promises

查看:88
本文介绍了理解JS承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想深入了解Promises如何在内部工作。
因此我有一些示例代码:

I would like to get a deeper understanding of how Promises work internally. Therefore I have some sample code:

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,最后打印出resolv值。

As you would predict, first p1 is resolved, afterwards p2 and in the end the final then prints the resolv value.

但是API ref声明如下:

But the API ref states the following:

"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)。

So it would be interesting to know WHEN exactly the "then" function is executed? Because the final "then" in the code is chained to the chainPromises(), I first thought that it would execute after the function chainPromises() returns something (in this case another promise).

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

If this would have been the case the "val" of the final "then" function would be the returned promise. But instead, the final "then" waits until all promises inside the first "then" which are returned have been resolved. This absolutely makes sense because in this way, the "then" functions can be stacked, but I do not really get how this is done, since the API spec. does not really cover what "then" returns and when the "then" functions is executed.

或换句话说,为什么最后的then函数等到所有Promise在chainPromises()函数中解析,而不是像API文档那样等待第一个返回的对象。

Or in other words, why does the final "then" function wait until all the Promises are resolved inside the chainPromises() function instead of just waiting for the first returned object as the API doc says.

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

I hope I could make clear what I mean.. :)

推荐答案

关于Promise解决方案



你做的事情在这里见证被称为递归然后能够解决。 Promises / A +规范中的promise解析过程包含以下子句:

About Promise resolution

The thing you're witnessing here is called recursive thenable resolution. The promise resolution process in the Promises/A+ specification contains the following clause:


onFulfilled或onRejected返回值x,运行Promise Resolution Procedure [[Resolve]](promise2,x)

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

ES6承诺规范(承诺展开)包含类似的条款。

The ES6 promise specification (promises unwrapping) contains a similar clause.

这要求当一个 resolve 操作发生时:在promise构造函数中,通过调用 Promise.resolve 或在您的情况下,在然后链中,承诺实现必须以递归方式解包返回的值(如果它是承诺)。

This mandates that when a resolve operation occurs: either in the promise constructor, by calling Promise.resolve or in your case in a then chain a promise implementation must recursively unwrap the returned value if it is a promise.

这意味着如果 onFulfilled 然后)返回一个值,尝试自己解析promise值,从而以递归方式等待整个链。

This means that if onFulfilled (the then) returns a value, try to "resolve" the promise value yourself thus recursively waiting for the entire chain.

这意味着以下内容:

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");
});



这是一个好主意吗?



这是承诺规范过程中备受争议的话题,第二个没有表现出这种行为的链式方法已被讨论但是已经决定(仍然可以在Chrome中使用,但很快就会删除)。你可以阅读在这个esdiscuss主题中的整个辩论。 此行为是出于实际原因,因此您无需手动执行此操作。

Is it a good idea?

It's been the topic of much debate in the promises specification process a second chain method that does not exhibit this behavior was discussed but decided against (still available in Chrome, but will be removed soon). You can read about the whole debate in this esdiscuss thread. This behavior is for pragmatic reasons so you wouldn't have to manually do it.

值得一提的是,其他语言不这样做,Scala中的未来或C#中的任务都没有这个属性。例如,在C#中,您必须在任务上调用 Task.Unwrap ,以便等待其链解析。

It's worth mentioning that other languages do not do this, neither futures in Scala or tasks in C# have this property. For example in C# you'd have to call Task.Unwrap on a task in order to wait for its chain to resolve.

这篇关于理解JS承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆