为什么等待仅适用于javascript中的异步函数?

时间:2018-04-03 23:47:25

标签: javascript asynchronous async-await

通过这个tutorial,让我理解为什么await仅适用于async函数。

从教程:

  

如上所述,await仅适用于异步函数。

根据我的理解,async将函数返回对象包装成Promise,因此调用者可以使用.then()

async function f() {
  return 1;
}

f().then(alert); // 1

await等待承诺在async函数内解决。

async function f() {

  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("done!"), 1000)
  });

  let result = await promise; // wait till the promise resolves (*)

  alert(result); // "done!"
}

f();

在我看来,他们的用法没有关系,有人可以解释一下吗?

2 个答案:

答案 0 :(得分:5)

代码在await上变为异步-我们不知道要返回什么

await除了等待承诺解决之外,还立即将代码执行返回给调用者。 await之后的函数内的所有代码都是异步的。

  • async是用于兑现承诺的合成糖。
  • 如果您不想在await返回承诺,那么异步代码中的明智选择是什么?

让我们看下面的错误代码,看看返回值的问题:

function f() {
  // Execution becomes asynchronous after the next line, what do we want to return to the caller?
  let result = await myPromise;

  // No point returning string in async code since the caller has already moved forward.
  return "function finished";
}

我们可以再问一个问题:为什么我们没有await的同步版本,而不会将代码更改为异步?

我的观点是,出于很多原因,设计使同步异步代码变得困难。例如,这会使人们很容易意外地冻结整个应用程序等待异步函数返回时。


要进一步说明asyncawait的运行时顺序:

async function f() {

  for(var i = 0; i < 1000000; i++); // create some synchronous delay

  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("done!"), 1000)
  });

  console.log("message inside f before returning, still synchronous, i = " + i);

  // let's await and at the same time return the promise to the caller
  let result = await promise;
  console.log("message inside f after await, asynchronous now");

  console.log(result); // "done!"

  return "function finished";
}

let myresult = f();
console.log("message outside f, immediately after calling f");

控制台日志输出为:

message inside f before returning, still synchronous, i = 1000000 
message message outside f, immediately after calling f 
message inside f after await, asynchronous now 
done!

答案 1 :(得分:2)

asyncawait都是元关键字,允许以看起来同步的方式编写异步代码。 async函数提前告诉编译器函数将返回Promise并且不会立即解析值。要使用await而不阻止线程async 必须

async function f() {
    return await fetch('/api/endpoint');
}

相当于

function f() {
    return new Promise((resolve,reject) => {
        return fetch('/api/endpoint')
        .then(resolve);
    });
}