使用await时是否会阻止它所使用的功能?

时间:2017-11-19 03:19:15

标签: javascript async-await

我在下面有async函数:

async LoadEditForm() {
    const { default : EditHero } = await import('./EditHero');
    this.setState({ lazyEditHero: EditHero })
}

它在这里被称为:

handleEnableAddMode = async () => {
    await this.LoadEditForm();
    this.setState({
        addingHero: true,
        selectedHero: { id: '', name: '', saying: '' }
    });
}  

我对上面的代码有疑问:

  1. await this.LoadEditForm();函数中的这一行:handleEnableAddMode,是否会阻止该函数?换句话说,this.setState(...)函数会立即被调用,还是等待await调用完成。
    • 因为我听到有人说async/await的概念是允许你以同步方式编写异步代码。这让我很困惑。有人可以澄清吗?

3 个答案:

答案 0 :(得分:2)

通常await会一直保持,直到收到成功结果,因为承诺已“解决”,或者由于承诺被“拒绝”而遇到错误。

如果这两个事件都没有发生,那么您的承诺就会被破坏,而await可能永远不会完成。

答案 1 :(得分:2)

当您调用Asyc函数时,它将返回一个promise,每当您在异步函数中返回一个值时,您的promise将被解析,如果您抛出异常,您的承诺将被拒绝。另一方面,await表达式暂停执行异步函数并等待传递的Promise的解析,然后恢复异步函数的执行并返回已解析的值。

根据Mozile文档中提供的样本:

function getProcessedData(url) {
  return downloadData(url) // returns a promise
    .catch(e => {
      return downloadFallbackData(url)  // returns a promise
    })
    .then(v => {
      return processDataInWorker(v); // returns a promise
    });
}


async function getProcessedData(url) {
  let v;
  try {
    v = await downloadData(url); 
  } catch(e) {
    v = await downloadFallbackData(url);
  }
  return processDataInWorker(v);
}

在您的情况下,您的setState将无法执行,直到您的await this.LoadEditForm();成为完成状态。但问题是你没有catch可能拒绝你的承诺。因此,如果函数b被拒绝,那么无论如何都会执行你的setState。

所以你必须在try ... catch语句中包装await函数和以下行。

答案 2 :(得分:2)

  

在这一行:await this.LoadEditForm();在handleEnableAddMode函数中,它是否阻止该函数?换句话说,会立即调用this.setState(...)函数,还是等待await调用完成。

其中一个不是另一个“换句话说”。

它没有阻止,它等待。控件将返回异步函数的调用者。当等待的承诺被解决或拒绝时,等待功能将恢复。

https://jsfiddle.net/7yxhqoo4/有一个简单的例子,因此:

function resolveAfterHalfSecond() { 
  return new Promise(resolve => {
    setTimeout(() => {
      resolve();
    }, 500);
  });
}

async function f1() {
  $("div").append("<p>before await</p>");
  await resolveAfterHalfSecond();
  $("div").append("<p>after await</p>");
}

function test()
{
  $("div").append("<p>before call async function</p>");
  f1();
  $("div").append("<p>after call async function</p>");
}

$(test);

立即输出如下:

  

调用异步函数之前

     在等待之前

     

调用异步函数后

半秒后,看起来像是

  

调用异步函数之前

     在等待之前

     

调用异步函数后

     在等待之后

awaitf1()中被点击时,它没有阻止,但立即返回test()并完成了该功能。当承诺得到解决后,f1()恢复了。