首页 文章

异步函数内的代码在其后面的代码之前执行

提问于
浏览
3

我正在javascript中探索async / await的概念 . 我知道async函数返回一个应该在未来时间内解决的promise并且它不会阻止代码的自然执行 . 这里我有一个我写的代码测试javascript的异步执行 .

console.log("1")
async function asyncFunc(){
  for(i=0;i<10000000;i++){
  }
  console.log("3")
}
asyncFunc().then(()=>{console.log('4')});
console.log("2");

我除了代码将以下列方式执行:

首先调用console.log(),然后调用异步函数 . 由于异步代码是非阻塞的,因此最后一个console.log()将执行,从而在控制台中打印2 . 之后,执行async函数内的console.log()并在控制台中打印3 . 最后,承诺将被解决,然后在内部执行console.log()并打印4.所以预期输出:1,2,3,4但实际上我输出为1,3,2,4 .

为什么它表现得像这样而不是我期望的方式

2 回答

  • 1

    该函数在完成运行之前不会返回一个promise(除非你 await 中有另一个promise) .

    循环运行(阻塞所有内容),然后评估 console.log("3") ,然后返回一个promise .

    调用函数继续运行(记录2) .

    最后,释放事件循环并调用传递给 then 的函数 .

    将函数标记为异步不会将其中的同步代码转换为异步代码 .

  • 5

    这里的答案很晚,而昆汀是完全正确的,但它看起来真的很简单 async 函数:

    async function foo() {
        console.log("a");
        await something();
        console.log("b");
        return 42;
    }
    

    该功能有两个部分:

    • 同步部分:所有内容(但不包括)第一个 awaitreturn (或者如果它刚刚结束) . 所以在上面,那是 console.log("a"); 和对 something 的调用(但不是等待其结果的位) .

    • 异步部分:首先是 await 之后的任何内容 .

    如果我们用明确的promises重写那个函数,它看起来就像这样(挥手细节):

    function foo() {
        console.log("a");
        return something().then(() => {
            console.log("b");
            return 42;
        });
    }
    

    所以看看你的功能:

    async function asyncFunc(){
      for(i=0;i<10000000;i++){
      }
      console.log("3")
    }
    

    ...我们可以看到函数中的代码 all 在其初始同步部分中,并且它返回的promise将使用 undefined 解析 .

    那么 whyasync 函数有一个同步部分吗?出于同样的原因,您传入 new Promise 的执行程序函数同步运行:因此它可以立即开始工作 .

    假设我们想在 fetch 周围做 async 包装,我们期待JSON响应:

    async function fetchJSON(...args) {
        const response = fetch(...args);
        return response.json();
    };
    

    如果没有同步部分(对 fetch(...args) 的调用),它将永远不会做任何事情,它的承诺永远不会解决 .

相关问题