如果javascript“异步”函数的主体中没有“等待”,它会以任何不同的方式执行吗? [复制]

Posted

技术标签:

【中文标题】如果javascript“异步”函数的主体中没有“等待”,它会以任何不同的方式执行吗? [复制]【英文标题】:Does a javascript "async" function's body execute in any diferent way if it doesn't have an "await" in it? [duplicate] 【发布时间】:2020-04-09 10:44:11 【问题描述】:

来自 MDN

异步函数通过事件循环以与其余代码不同的顺序运行,

但是我不明白这对于一个不显式返回任何内容且根本不使用 await 的简单函数意味着什么。在这种情况下声明一个函数 async 是否有用?它会在稍后执行以允许页面在执行时响应吗?我的测试显示它是同步执行的,根本没有延迟:

async function foo() 
  console.log('Start heavy stuff');
  for (let i = 0; i < 90000000; ++i) 
    Math.random()
  
  console.log('Fnish heavy stuff')


foo();
console.log('All done, synchronously');

日志以期望的顺序显示,那么在这种情况下是否可以使用使此函数异步?这与使用setTimeout(foo, 0) 调用此函数有什么相似之处吗?

【问题讨论】:

除非你的函数中有异步代码,否则没有区别。 【参考方案1】:

async 函数同步运行,直到到达第一个 awaitreturn,抛出错误,或者代码执行刚刚在函数末尾运行(就像在你的函数中一样)。此时,该函数返回一个承诺。

在这种情况下,声明一个函数async 是否有用?

不是在那种特定情况下,不。该函数似乎没有任何理由返回一个承诺,并且正如您在测试中看到的那样,它的所有工作都是同步完成的。

是否会在稍后执行以允许页面在执行时做出响应?

没有。

当函数async 不使用await 时,它确实没有充分的理由声明它。它使它返回一个承诺,但除此之外不做任何其他事情。也许如果你打算在承诺链中使用它,但是......

下面是一个稍微不同的例子,说明async 函数是如何同步运行的:

async function example1() 
    console.log("this is done synchronously");
    await Promise.resolve();
    console.log("this is done asynchronously");


console.log("before calling example1");
example1().then(() => 
    console.log("promise from example1 was fulfilled");
);
console.log("after calling example1");

输出:

在调用 example1 之前 这是同步完成的 调用 example1 后 这是异步完成的 来自 example1 的承诺已实现

【讨论】:

答案写得很好。 +1,我想这可以移动到欺骗目标。 :) @CodeManiac - 谢谢。我应该知道有一个很好的欺骗目标。我认为这个问题的措辞已经足够具体了,我将把它留在这里,但是......【参考方案2】:

不,像示例中的“重”Math.random() 循环这样的同步代码不会以任何不同的方式运行。

但是,不同之处在于,使用 async 函数构建类似这样的东西,它可以让其他代码运行,这几乎是微不足道的,因为使它成为协程/生成器/...的所有繁重工作都发生在转译或在运行时。

function delay(ms) 
  return new Promise((resolve) => setTimeout(resolve, ms));


// or maybe:

function continueSoon() 
  return new Promise((resolve) => setImmediate(resolve));


async function foo() 
  console.log("Start heavy stuff");
  for (let i = 0; i < 90000000; ++i) 
    Math.random();
    if(i % 10000 == 0) await delay(10);
  
  console.log("Fnish heavy stuff");

【讨论】:

以上是关于如果javascript“异步”函数的主体中没有“等待”,它会以任何不同的方式执行吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

全局调用异步函数时出错:“等待仅在异步函数和模块的顶层主体中有效”?

JavaScript String 简易版烟花

16.Generator 函数的异步应用

Generator 函数的异步应用

JavaScript的异步编程

javascript异步编程之generator(生成器函数)与asnyc/await语法糖