解决承诺是一个非同步过程吗?

时间:2017-09-20 15:23:20

标签: javascript ecmascript-6 es6-promise

我确信下面的所有代码(resolve(Promise.resolve(p2))除外)都是同步的。 所以我希望结果是p2,因为p2.then首先运行。但是p1首先出现在控制台中。

MDN与此问题无关。 规范是否有一些细节?有人能够逐步明确解决承诺会发生什么吗?

Chrome v60.0.3112.113

我的代码是:

var p1 = new Promise(function(resolve, reject){
  resolve("p1");
});

var p2 = new Promise(function(resolve, reject){
  //resolve("p2");
  var tempP = Promise.resolve("p2"); // for better description in discussion
  resolve(tempP);
});

p2.then(function(value){
  console.log(value)
})
p1.then(function(value){
  console.log(value);
});

4 个答案:

答案 0 :(得分:1)

这是预期的行为。

Promise.resolve()返回一个保证异步的promise。因此,它返回的值将始终在调用后的下一个事件循环中最早解析。所以在这种情况下会发生什么:

P2返回承诺
P1返回一个承诺

下一轮

P2调用then(),解析为下一个循环的新承诺
P1调用then()回调,该回调解析为打印的值

下一轮

P2的退回承诺结算并打印

答案 1 :(得分:1)

  

我确信以下所有代码(resolve(Promise.resolve(p2))除外)都是同步的。

没有。 then回调从不同步调用,它们总是异步的(这很好)。这意味着他们的相对顺序是不确定的,取决于履行相应承诺的时间。如果您关心回调的顺序,请通过将承诺链接到彼此来明确它。

示例中的履行顺序取决于您解决承诺的值。请注意,new Promiseresolve中的p1回调以及p2同步都是同步的。每个分辨率都被放入队列中 - 至少使用您似乎正在使用的本机ES6承诺。不同之处在于,您的p2已使用Promise.resolve("p2")解决,p2将使用其他承诺的结果解析p1 - 再次将其重新放回队列。因此,p2的实现首先发生,并且在new Promise的实现回调之前调用回调。

所以一步一步发生的是

  1. resolve调用构造函数回调,而后者又调用
  2. "p1"带有值new Promise的新承诺 - 实现它
  3. p1返回,值将分配给new Promise
  4. "p2"调用构造函数回调,而后者又调用
  5. 使用值resolve
  6. 构建另一个承诺
  7. resolve是它的新承诺 - 它会在该承诺完成时添加另一个new Promise作为回调
  8. 内部承诺安排回调,因为它已经完成
  9. p2返回,值将分配给p2.then
  10. 调用p1.then并注册履行回调
  11. 调用p1并安排履行回调,因为p2已经履行
  12. 之后,异步:

    1. 调用内部promise的回调并使用值"p2解析p1 - 完成它并安排其注册的回调
    2. 调用"p1"回调并记录p2
    3. 调用"p2"回调并记录Instance

答案 2 :(得分:-1)

p1和p2都是异步的,因为你正在创建一个Promise。 New Promise()创建一个新的promise,一旦创建它,​​就会执行以下代码,但Promise中的执行会在稍后(或同时; async)完成。

p2.then在p1.then之前没有执行。一旦promise解析,执行.then函数,p1在p2

之前解析

答案 3 :(得分:-1)

您在上面编码:

var p2 = new Promise(function(resolve, reject){
    resolve(Promise.resolve("p2"));
});

等同于:

var p2 = new Promise(function(resolve, reject) {
    resolve(new Promise(function(resolve1, reject1) {
        resolve1("p2"); 
    }));
});

创建一个新的承诺,虽然立即解决,但将在调用队列的末尾执行。