首页 > 解决方案 > Promise 不适用于 Node.js 嵌套异步

问题描述

我在 Node.js 中为不同的 redis 模式设计编写了许多基准脚本。我尝试按顺序运行所有基准函数。我在 StackOverflow 上遇到了许多异步模板来解决这个问题。这些模板在简单的异步上运行良好,但我的单个基准测试函数包含许多嵌套的异步函数,当我使用这些模板时,嵌套的异步函数按顺序运行,但整个基准测试并行运行。这是示例:

单个基准测试结果如下所示: 单个基准测试

当我使用 Promise 模板运行所有基准测试时: 许多基准测试

基准函数的样子。其他具有相同的结构:

async function CMbenchmark(redis,size,flag){
var time_stamp0;
var time_stamp1;
var time_stamp2;
redis.flushall().then(()=>{
//initialize data
time_stamp0 = performance.now();
  console.log("benchmark size: "+size);
  CMinitializeFakeData(redis,size)
}).then(()=>{
  time_stamp1 = performance.now();
  console.log("time for initialize data: "+size);
  console.log(time_stamp1-time_stamp0);
  searchEntryByBM(redis,"gender","male");
}).then(()=>{
  time_stamp2 = performance.now();
  console.log("time for search operation: ");
  console.log(time_stamp2-time_stamp1);
  redis.memory("stats").then(function(result){
    console.log(result[0]+": "+result[1]/1000000+"MB");
    console.log(result[2]+": "+result[3]/1000000+"MB");
  });
});
}

我尝试了一些执行功能,许多其他变体看起来相似:

async function benchAll(){
  Promise.resolve(benchmark2(redis,size,0)).then(function(){
    return Promise.resolve(benchmark(redis,size,0));
  }).then(function(){
    return Promise.resolve(CMbenchmark(redis,size,0));
  });
}

async function benchAll2(){
  const result1 = await benchmark(redis,size,0);
  const result2 = await benchmark2(redis,size,0);
  const result3 = await CMbenchmark(redis,size,0);
}

指的是:我应该如何调用3个函数才能一个接一个地执行它们?. 回调链也不起作用。除了寻找解决方案。我也在寻找关于为什么回调链适用于简单异步而不是嵌套异步的解释。


更新:

根据@d-_-b的回答在promise中添加return后,问题依然存在。

标签: javascriptnode.jspromise

解决方案


你需要return在下一个你想要的承诺.then()

你很亲近!每次调用.then(function(){...})时都应该返回一些值,以便下一个.then()接收它。

redis.flushall().then(()=>{
  //initialize data
  time_stamp0 = performance.now();
  console.log("benchmark size: "+size);
  return CMinitializeFakeData(redis,size)// <-- added return here
}).then(()=>{
  time_stamp1 = performance.now();
  console.log("time for initialize data: "+size);
  console.log(time_stamp1-time_stamp0);
  return searchEntryByBM(redis,"gender","male"); // <-- added return here
}).then(()=>{
  time_stamp2 = performance.now();
  console.log("time for search operation: ");
  console.log(time_stamp2-time_stamp1);
  redis.memory("stats").then(function(result){
    console.log(result[0]+": "+result[1]/1000000+"MB");
    console.log(result[2]+": "+result[3]/1000000+"MB");
  });
});

推荐阅读