为什么此异步功能正在同步运行?

时间:2019-08-17 10:48:59

标签: javascript asynchronous

我在这里有一些代码...

async function test() {
    for(let i = 0; i < 10000; i++){
        console.log("test");
    }
}

console.log("a");
test();
console.log("b");

现在,我的理解是,test()应该异步运行,如果我想在例程完成后运行该例程,则可以在其后使用.then()

我不是在这里这样做,但是可以肯定的是,它应该只是在后台处理其他事情,而其他事情仍在继续吗?有了这样的理解,我会期望这样的输出:

a
b
test
test
..etc

但是我实际上得到的是...

a
test
test
...etc

b

为什么会这样?似乎console.log("b")一直等到test()完成,但这是同步的行为。

很抱歉以前是否曾提出过类似的要求,但我本人却找不到任何东西。

5 个答案:

答案 0 :(得分:2)

将某些内容设置为async会将返回对象包装到Promise中。承诺用于处理异步行为,但是test函数的内容本质上不是异步的。相反,如果要将内容包装到setTimeout函数中,则会导致延迟,该延迟将模仿异步行为并符合您期望的结果。

async function test() {
  setTimeout(() => {
    for(let i = 0; i < 2; i++){
        console.log("test");
    }
  })
}

console.log("a");
test();
console.log("b")

如果要设置可以锁定浏览器主线程的后台任务,则应签出WebWorkers。它们是将对性能有影响的任务卸载到单独线程上的一种方法。

答案 1 :(得分:1)

100 x 100函数中的同步代码同步运行。在所有同步代码完成后,例如,如果运行到async中,解释器将仅在调用异步函数(此处为console.log("b");)之后移至下一行。

在这里,由于await中没有await或任何异步操作,因此test会运行到下一行(记录test)之前的末尾

这与Promise constructor的运行方式非常相似。

答案 2 :(得分:1)

来自MDN:

  

异步函数可以包含await表达式,该表达式暂停异步函数的执行并等待传递的Promise的分辨率,然后恢复异步函数的执行并返回解析的值。

如果没有await表达式,则永远不会“暂停”协程,协程将同步执行而不会运行其他功能。

答案 3 :(得分:0)

一个异步函数意味着该函数内部的内容需要进行一些异步调用。就像您在测试函数中进行了Http调用一样。

并且由于函数内部没有异步的东西(只有正常的循环),因此函数将按顺序执行,直到执行完毕。

答案 4 :(得分:0)

async关键字并不意味着该函数将异步运行。要异步运行它,请使用setTimeout或Promise等。

function test() {
  setTimeout(() => {
    for(let i = 0; i < 3; i++){
        console.log("test");
    }
  });
}

console.log("a");
test();
console.log("b");

异步关键字通常与Promiseawait关键字一起使用,以同步方式编写异步代码(要使用await关键字,我们需要将代码放入异步函数中)

function test() {
  return new Promise( res => {
    for(let i = 0; i < 3; i++){
        console.log("test");
    }
    res();
  });
}

async function start() {
  console.log("a");
  await test();
  console.log("b");
}

start();