嵌套节点 async.eachSeries

Posted

技术标签:

【中文标题】嵌套节点 async.eachSeries【英文标题】:Nesting node async.eachSeries 【发布时间】:2014-10-31 23:52:00 【问题描述】:

与异步模块打了半天,但嵌套几层时无法正常工作。

所以这工作正常:

var async = require('async') var myarr = [“外 - A”,“外 - B”]; var myarr2 = [“内部 - A”,“内部 - B”]; 变种内完成=真; async.eachSeries(myarr,函数(项目,outerCallback) console.log('处理项' + item); 异步系列([ 功能(回调) 采取时间(2000,项目,回调) , 功能(回调) 采取时间(1000,项目,回调) , 功能(回调) 外部回调(); ],函数(错误) console.log("---外部序列---") ) ,函数(错误) console.log("---外循环---") ); 函数采取时间(毫秒,味精,回调) console.log("开始" + ms + " ms 任务来自" + msg); 设置超时(函数() console.log("完成" + ms + " ms 任务来自" + msg); 打回来(); , 小姐);

它会像这样按顺序很好地输出所有内容:

处理项目外 - A 从外部开始 2000 毫秒任务 - A 从 Outer - A 完成了 2000 毫秒的任务 从外部启动 1000 毫秒任务 - A 从 Outer - A 完成 1000 毫秒的任务 处理项目外 - B 从 Outer - B 开始 2000 ms 任务 从 Outer - B 完成 2000 毫秒的任务 从 Outer - B 开始 1000 ms 任务 从 Outer - B 完成 1000 毫秒的任务 ---外环---

但是当我尝试像这样嵌套另一个 eachSeries 循环时:

var async = require('async') var myarr = [“外 - A”,“外 - B”]; var myarr2 = [“内部 - A”,“内部 - B”]; 变种内完成=真; async.eachSeries(myarr,函数(项目,outerCallback) console.log('处理项' + item); 异步系列([ 功能(回调) 采取时间(2000,项目,回调) , 功能(回调) 采取时间(1000,项目,回调) , 功能(回调) async.eachSeries(myarr2,函数(item2,outerCallback2) console.log('处理项' + item2); 异步系列([ 功能(回调2) 采取时间(2000,项目2,回调2) , 功能(回调2) 采取时间(1000,项目2,回调2) ],函数(错误) console.log('---内部序列---') ) ,函数(错误) console.log("---内部循环---") ); 外部回调(); ],函数(错误) console.log("---外部序列---") ) ,函数(错误) console.log("---外循环---") ); 函数采取时间(毫秒,味精,回调) console.log("开始" + ms + " ms 任务来自" + msg); 设置超时(函数() console.log("完成" + ms + " ms 任务来自" + msg); 打回来(); , 小姐);

这样进入第二个eachSeries循环时会丢失执行顺序:

处理项目外 - A 从外部开始 2000 毫秒任务 - A 从 Outer - A 完成了 2000 毫秒的任务 从外部启动 1000 毫秒任务 - A 从 Outer - A 完成 1000 毫秒的任务 处理项目内部 - A 从内部启动 2000 毫秒任务 - A 处理项目外 - B 从 Outer - B 开始 2000 ms 任务 从 Inner - A 完成 2000 毫秒的任务 从内部开始 1000 毫秒任务 - A 从 Outer - B 完成 2000 毫秒的任务 从 Outer - B 开始 1000 ms 任务 从 Inner - A 完成 1000 毫秒的任务 ---内在序列--- 从 Outer - B 完成 1000 毫秒的任务 处理项目内部 - A 从内部启动 2000 毫秒任务 - A ---外环--- 从 Inner - A 完成 2000 毫秒的任务 从内部开始 1000 毫秒任务 - A 从 Inner - A 完成 1000 毫秒的任务 ---内在序列---

我还尝试了瀑布、mapSeries 等,但执行顺序相同或混乱。我做错了什么还是异步模块不支持这种嵌套?

【问题讨论】:

【参考方案1】:

您没有拨打outerCallback2,您没有拨打callback,而是立即拨打outerCallback

固定:

async.eachSeries(myarr, function( item, outerCallback) 
  ,----------------------------------------'
  |  console.log('Processing item ' + item);
  |  async.series([
  |      function(callback) 
  |                 `--------------,
  |          takeTime(2000, item, callback)
  |      ,
  |      function(callback) 
  |                 `--------------,
  |          takeTime(1000, item, callback)
  |      ,
  |      function(callback) 
  |     ,-----------'
  |     |     async.eachSeries(myarr2, function( item2, outerCallback2) 
  |     |    ,---------------------------------------------'
  |     |    |   console.log('Processing item ' + item2);
  |     |    |   async.series([
  |     |    |      function(callback2) 
  |     |    |          takeTime(2000, item2, callback2)
  |     |    |      ,
  |     |    |      function(callback2) 
  |     |    |          takeTime(1000, item2, callback2)
  |     |    |      
  |     |    |  ], function(err) 
  |     |    |      console.log('---INNER SEQUENCE---')
  |     |    `--->  outerCallback2(err); // <<<
  |     |       )
  |     |   , function(err)
  |     |      console.log("---INNER LOOP---");
  |     `--->  callback(err); // <<<
  |         );
  |     
  | ], function(err) 
  |      console.log("---OUTER SEQUENCE---")
  `--->  outerCallback(err); // <<<
    )
, function(err)
    console.log("---OUTER LOOP---")
    console.log("everything done");
);

【讨论】:

创造了奇迹和出色的作品,可以更好地掌握像这样的嵌套结构中的回调。百万感谢Bergi! 天哪,谢谢,这很有帮助,有没有更“基于函数调用”的方法来做到这一点? @timhc22:“基于函数调用”是什么意思?如果你不喜欢传递回调并关心返回值,你应该看看 Promise。 在主要使用 Symfony2 和 php 之后,我仍然在进入 Node(和 javascript)的工作方式,所以我仍在努力寻找分解代码块的最佳方法,所以一切都很好和模块化!

以上是关于嵌套节点 async.eachSeries的主要内容,如果未能解决你的问题,请参考以下文章

嵌套节点 async.eachSeries

XSLT - 如何将节点内的内联/转义 XML 视为嵌套节点

更改嵌套节点的值

Angular Material - 扁平树和嵌套树之间的区别

C#获取xml文档中的所有节点但忽略嵌套节点

取消嵌套节点数据库调用