为什么Promise和Async / await以不同的顺序解决Promise?

时间:2019-09-05 06:06:18

标签: javascript async-await es6-promise

从我读过的所有内容来看,异步/等待只是诺言的句法糖。因此,假设promise_1promise_2都是诺言,我希望以下两个功能可以相同地工作:

function promises(promise_1, promise_2) {
    promise_1.then((val) => {
        console.log(val);
        promise_2.then((val2) => {
            console.log(val2);
        });
    });
}
async function asyncawait(promise_1, promise_2) {
    console.log(await promise_1);
    console.log(await promise_2);
}

但是,在测试它们时,我注意到promises函数比异步函数更早地解决了第二个承诺:

let func;
async function test() {
    let promise_1 = Promise.resolve("first");
    let promise_2 = Promise.resolve("second");

    func(promise_1, promise_2);

    console.log("await first");
    await promise_1;
    console.log("awaited first");

    console.log("await second");
    await promise_2
    console.log("awaited second");
}

运行

func = promises;
test();

产生以下输出:

await first
first
second
awaited first
await second
awaited second

请注意,在等待promise_1之后,promise_1promise_2都已解决。

但是,跑步

func = asyncawait;
test();

产生以下(预期的)输出:

await first
first 
awaited first
await second
second
awaited second

与承诺决议交织在一起。

是什么原因导致分辨率顺序出现差异?

1 个答案:

答案 0 :(得分:0)

是的,正如您正确地说过的那样:“异步/等待只是诺言的语法糖”。考虑一下,

function foo(flag){
  return new Promise((res, rej) => {
    setTimeout(() => {
      if(flag) res("Resolved");
      else rej("Rejected")
    },1000);
  })
}

这里的关键是异步函数总是返回一个promise。参见return value of a async function

现在,让我们使用此功能

function useFoo(){
  return foo(true).then(val => { console.log(val); return val; })
                  .catch(err => { console.log(err); throw err; })
} 

这等同于

async function useFoo(){
  try{
    const val = await foo(false);
    console.log(val);
    return val;
  }catch(err){
    console.log(err);
    throw err;
  }
}

您的行为的解释,

(function(){
  foo(1).then((x)=> console.log(x)); 
  console.log("after foo()");
})()

使用相同的foo函数,由于foo()是一个异步函数,因此上述代码段先记录after foo()。对于执行程序函数的同步操作,将立即执行。

这就是“异步/等待只是诺言的语法糖”的方式