Async / await代码没有按预期执行

时间:2018-01-16 18:20:30

标签: node.js asynchronous async-await

根据我对异步的理解,这样的代码应该是非阻塞的,这意味着无论代码的某些部分或某些功能是否尚未完成,代码总是会被执行。这就是我做 longProcess()的原因,这是一个简单的函数,可能需要几秒钟才能完全执行。但是,在我的例子中并非如此。在 t1()之后,当 longProcess()被调用时,代码执行会暂停,直到 longProcess()完成,然后 t2( )被执行。

所以它的代码是错误的,或者我只是没有得到异步原则。我想如果有人会如此友好地纠正代码或指向一些更好的来源,我可以在这个问题上阅读更多内容。

function t1(){
  console.log(Date.now() + ' from t1(); ');
}

function longProcess(){
  let i = 0;
  while (i < 10000000000) {
    i += 1;
  }
  funcGetTime();
}

function t2(){
  console.log(Date.now() + ' from t2(); ');
}

function funcGetTime(){
  console.log(Date.now());
}

async function main(){
  await t1();
  await longProcess();
  await t2();
}

main();

控制台输出

1516123716603 from t1();
1516123727318               // from longProcess(), blocks here
1516123727320 from t2();

2 个答案:

答案 0 :(得分:1)

让你明白。 Node.js是单线程语言。如果您编写的代码没有I / O阻塞请求,如数据库读取,文件读取。代码将按顺序运行。这就是你的代码在这里做的事情。如果你想要I / O阻止。我在下面的代码中添加了settimout。

你完全误解了node.js中的async / await。

node.js本身是异步的。您无需async/await即可asynchronous。添加async/await以使node.js代码运行synchronous,这意味着按顺序。

async function main(){
  await t1();
  await longProcess();
  await t2();
}

首先t1表示完全执行longProcess,然后t2

如果你写这样的代码

 function main(){
   t1();
   longProcess();
   t2();
}

它将按您的意愿执行。

t1longProcesst2类似。没有人会等待彼此完成。

现在你要说明为什么我的结果对于这两种方法都是一样的。 当您执行Async / await而不执行Async / await?

原因是你的功能是正常功能,它们不是I / O事件。所以在这种情况下,您的代码将按顺序执行。要查看您想要的更改代码。

function t1(){
  console.log(Date.now() + ' from t1(); ');
}

function longProcess(){
  setTimeout(function(){
  let i = 0;
  while (i < 10000000000) {
    i += 1;
  }

  funcGetTime();
  }, 0);
}

function t2(){
  console.log(Date.now() + ' from t2(); ');
}

function funcGetTime(){
  console.log(Date.now());
}

 function main(){
   t1();
   longProcess();
   t2();
}

main();

现在你了解它是如何运作的。

答案 1 :(得分:1)

简单地说,异步函数返回一个promise并通过将一个函数声明为async,允许在其中使用'await'。 'await'的作用是允许你(在异步函数中)获得已解决的promises的结果而不使用'.then'的promise链。

我已经稍微改变了你的代码以试图解释这种行为:

function t1(){
console.log(Date.now() + ' from t1(); ');
}
 function longProcess(someNumber){
return new Promise((resolve, reject) =>{
   //an async operation that will be executed after the main call stack has finished
   setTimeout(function () {
       let i = 0;
       while (i < 1000000000) {
           i += 1;
       }
       console.log(`this is ${someNumber}`);
       resolve();
   }, 0);
   })}
function t2(){
console.log(Date.now() + ' from t2(); ');
}async function main(){
//non blocking
 t1();
longProcess(0);
t2();

console.log('------');
//blocking
await longProcess(1);
t1();
longProcess(2);
t2();
console.log('HI');
}main();