为什么我的async / await函数异常?(Javascript)

时间:2017-12-15 05:23:21

标签: javascript

这是我的Javascript编码。我认为结果是1 2 3 4 5。



async function fn1 () {
    console.log(1);
    await fn2();
    console.log(3);
};

async function fn2 () {
    console.log(2);
};

fn1();
new Promise((resolve, reject) => {
    console.log(4)
    resolve()
}).then(() => {
    console.log(5)
})




但是。结果如下:1 2 4 5 3。

4 个答案:

答案 0 :(得分:5)



// functions declaration

async function fn1 () {
    console.log(1);
    await fn2(); // wait for async function fn2(which gets dispatched on thread 3) => so console.log(2) should be here chronologically
    console.log(3);
};

async function fn2 () {
    console.log(2);
};


// thread 1 starts (the actual execution code)

fn1(); // since fn1 is async it gets dispatched on thread 2

new Promise((resolve, reject) => {
    console.log(4)
    resolve() // trigger () => {console.log(5)}
}) // promise declaration
.then(() => {
    console.log(5)
}) // execute the promise right away




简单地说,console.log(1)console.log(2)console.log(3)按时间顺序在一个主题上发生,console.log(4)console.log(5)按时间顺序在另一个主题上发生。它们相互交叉。

旁注: JavaScript本身是单线程的,不支持多线程!(除了Web worker等,在我们的" async"的上下文中)我简化了很多,并在这里使用术语thread只是为了让它易于理解。为了不误解您异步操作的概念,如果您不确定异步操作在JavaScript中的工作方式,我建议您阅读QnA

答案 1 :(得分:0)

问题是JS代码本质上是异步的。因此,在执行'3'打印之前,它已经触发了其他指令,并且在结束之前结束了这些指令。

答案 2 :(得分:0)

上面fn1()和新Promise()的执行是异步执行的,这就是指令顺序独立的原因。如果您想获得所需的结果,可以尝试以下代码:

{{1}}

答案 3 :(得分:0)

你必须了解堆栈和队列:

更多信息:堆叠和队列videoducumentation

执行new Promise(fnResolvingOrRejecting)时,会立即调用函数fnResolvingOrRejecting,因此它位于同一堆栈中。什么都没有排队。

如果你了解什么是堆栈和队列,你可以解释你的代码更好地省略混淆的异步和等待语法。

一旦你理解它实际上做了什么,语法就会真正改善代码但是在这种情况下我会把它留下来,这样你就可以看到执行什么代码作为回调/结果处理程序以及什么代码在堆栈上。

function fn1 () {
  console.log(1);//on the same stack as calling fn1
  fn2()//executing fn2
  .then(//first queued
    () => console.log(3)
  );
};

function fn2 () {
  return new Promise(
    (resolve)=>{
      console.log(2);//on the same stack as calling fn1
      resolve();
    }
  );
};

fn1();//calling fn1 immediatly logs 1 and 2 because they are on the same stack
new Promise((resolve, reject) => {
  //after calling fn1 and queing console.log(3) this is executed because it's on
  //  the same stack
  console.log(4)
  resolve()
}).then(() => {//second queued
  console.log(5)
})