【问题标题】:Nodejs - async/await - nested async calls without await is still blocking?Nodejs - 异步/等待 - 没有等待的嵌套异步调用仍然阻塞?
【发布时间】:2021-04-23 18:27:06
【问题描述】:

我希望 datafx 中的 saveData() 调用不会阻止任何内容,因为没有“等待”,但是当我检查日志和时间戳时,我注意到“主要完成”日志被延迟,即使“检索数据”不是.

async function mainCaller(){
  // do something and then trigger call to get data
  let id = 13;
  let data = await datafx( id );  <-- this gets blocked for saveData() - why?
  LOG( `main done` );
}

async function datafx( id ){
  // get data
  let data = await getData( id );
  // cleanup data
  // save data but don't wait for it
    // datafx does not wait for it as expected
    // however, mainCaller() is somehow "delayed" by it based on log timestamps
  saveData(id, data );
  LOG( `retrieved data` );
  return data;
}

async function getData(id){ return await dbRead(id); }
async function saveData(id, data){ return await dbSave(id, data); }
  1. mainCaller() 中的“await”是否在等待所有异步调用,包括嵌套调用?
  2. 正确吗?
  3. 有没有更好的方法来实现嵌套异步调用以避免调用者的延迟?
  4. 我可以确认“saveData()”调用正在影响我删除它,我看到 mainCaller 在 datafx 返回后立即继续。

【问题讨论】:

  • saveData() return promise 并且你没有等待,所以它打印 'main done'

标签: node.js async-await nested nonblocking


【解决方案1】:

考虑以下代码 -

function timeoutPromise(interval) {
  return new Promise((resolve, reject) => {
    setTimeout(function () {
      resolve("done");
    }, interval);
  });
};

async function timeTest1() {
  await timeoutPromise(3000);
  await timeoutPromise(3000);
}

async function timeTest3() {
 await timeoutPromise(3000);
}

async function timeTest2() {
  await timeoutPromise(3000);
  timeTest3();
}

async function test1() {
  let startTime = Date.now();
  await timeTest1();
  let finishTime = Date.now();
  let timeTaken = finishTime - startTime;
  console.log("Time taken for test1 in milliseconds: " + timeTaken);
}

async function test2() {
  let startTime = Date.now();
  await timeTest2();
  let finishTime = Date.now();
  let timeTaken = finishTime - startTime;
  console.log("Time taken for test2 in milliseconds: " + timeTaken);
}

async function test3() {
  let startTime = Date.now();
  timeTest1();
  let finishTime = Date.now();
  let timeTaken = finishTime - startTime;
  console.log("Time taken for test3 in milliseconds: " + timeTaken);
}

test1();
test2();
test3();

这个程序的输出如下-

Time taken for test3 in milliseconds: 0
Time taken for test2 in milliseconds: 3004
Time taken for test1 in milliseconds: 6008

您的问题的答案如下-

mainCaller() 中的“等待”是否正在等待所有异步调用,包括嵌套调用?

考虑上述示例代码中的函数test2,答案是

有没有更好的方法来实现嵌套异步调用以避免 来电延迟?

是的,您需要在调用datafx 函数时从mainCaller 中删除await,与函数test3 中的描述相同

【讨论】:

  • 我在问题中所指的场景是 test2() -“test2 花费的时间,以毫秒为单位:3004”,这就是我期望它的行为方式。但是,我观察到好像 test2() 等待“timeoutPromise(3000)”完成并报告 test2 花费了 6000 毫秒。
  • @Aikh,我已根据您的评论更新了我的答案
  • OP,新答案对您有帮助吗?如果是的话,你能接受吗?
猜你喜欢
  • 2018-06-04
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多