【问题标题】:Is resolving a promise an asychronous process?解决承诺是一个异步过程吗?
【发布时间】:2017-09-20 15:23:19
【问题描述】:

我确信下面的所有代码,除了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);
});

【问题讨论】:

    标签: javascript ecmascript-6 es6-promise


    【解决方案1】:

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

    没有。 then 回调从不同步调用,它们总是异步的(这很好)。这意味着它们的相对顺序是不确定的,并且取决于各自的承诺何时实现。如果您关心回调的顺序,请通过将 Promise 相互链接来使其明确。

    您的示例中的履行顺序取决于您解决承诺的值。请注意,new Promise 回调,因此您的 resolvep1p2 中都是同步的。每个解决方案都被放入一个队列中——至少对于您似乎正在使用的本机 ES6 承诺。不同之处在于您的p2 使用Promise.resolve("p2") 解析,这将使用另一个promise 的结果解析p2 - 它再次放回队列中。因此p1的实现首先发生,并且在p2的实现回调之前调用回调。

    那么一步一步发生的事情是

    1. new Promise 依次调用构造函数回调
    2. resolves 价值为 "p1" 的新承诺 - 兑现它
    3. new Promise 返回,并将值分配给p1
    4. new Promise 依次调用构造函数回调
    5. 构造另一个用值"p2"实现的承诺
    6. resolves 新的承诺 - 添加另一个 resolve 作为该承诺完成时的回调
    7. 内部承诺计划回调已经完成
    8. new Promise 返回并将值分配给p2
    9. p2.then 被调用并注册实现回调
    10. p1.then 被调用并安排履行回调,因为 p1 已经履行

    之后,异步:

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

    【讨论】:

    • 请问schedules the fulfillment callback是什么意思?和registers the fulfillment callback一样吗?
    • Using $.when().then() - 所以你没有使用 Promises
    【解决方案2】:

    这是预期的行为。

    Promise.resolve() 返回一个保证是异步的承诺。所以它返回的值总是最早在它被调用后的下一个事件循环中解析。所以在这种情况下会发生什么:

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

    下一个循环

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

    下一个循环

    P2 返回的 Promise 解析并打印

    【讨论】:

    • Promise.resolve() 根本不是异步的,它立即返回?
    • 是的@Bergi - 我调整了答案。 Promise.resolve() 返回一个保证是异步的承诺。你说得对,这是一个重要的区别。
    • 我认为您的意思是“P2 调用 then() 解析为新的承诺”是正确的,但它的表述很奇怪
    【解决方案3】:

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

    p2.then 不会在 p1.then 之前执行。 .then 函数在 promise 解决后执行,并且 p1 在 p2 之前解决

    【讨论】:

    • "但是 Promise 中的执行是稍后完成的" - 这是错误的,或者至少是错误的。 new Promise 回调是同步的 - 但是其中发生的可能是对异步函数的调用。
    【解决方案4】:

    你上面的代码:

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

    这会创建一个新的 Promise,尽管它会立即解决,但会在调用队列的末尾执行。

    【讨论】:

    • 请问,调用队列是指浏览器中Event Loop的“任务队列”吗?
    • 任务队列。
    猜你喜欢
    • 2019-03-19
    • 2020-07-04
    • 1970-01-01
    • 2016-12-06
    • 2015-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多