如何迭代创buildlogging集合并一次渲染?

我有很多从我的视图发送到控制器值的数组。 例:

year: ['2015','2016','2017'] cash: ['...','...','...'] . . . 

这些数组中的第0个索引在现金stream数据库表中形成一个logging。 第一笔logging,等等…现金stream是“财产”模型内的集合。 每当创build“财产”logging时,我都需要迭代创build这些“现金stream”。

我正在使用sails框架。 我无法迭代创build这些logging并一次渲染。 我不确定是否需要使用asynchronous任务来完成。

 Property.create(reqParams).exec(function(err, property) { if (err) { ... } else { var index = 0; var asyncTasks = []; for (index = 0; index < reqParams.year.length; index++) { asyncTasks.push(function(callback) { CashFlowProjections.create({ year: reqParams.year[index], belongsTo: property.id, cash: reqParams.cash[index], ...) .exec(function(err, cashflows) { callback(err, cashflows); }); }); } async.parallel(asyncTasks, function(err, results) { if (err) { res.handleError(0, err); } else { res.view('property/preview', { cashflows: results[0], ... }); } }); } } }); 

但是上面的代码是错误的,因为'索引'结果是所有logging的相同值,logging创build失败。

我也尝试过没有asynchronous任务,但是我在创build现金streamlogging之前遇到了“res.view”被执行的问题。 有人可以用这个指导我吗?

问题在于variablesindex的范围。 index的作用域是从第1行开始的函数asyncTasks成为一个函数数组,它们是闭包 – 它们共享variables和它们的包围范围。 由于这些函数是asynchronous调用的,所以在for循环结束之后, index的值被调用的时间为reqParams.year.length

为了解决这个问题,你可以为每个函数创build一个单独的范围,并在这些范围内创build一个index的副本,而不会受到原始indexindex++的影响。 喜欢这个:

 for (index = 0; index < reqParams.year.length; index++) { (function(index) { asyncTasks.push(function(callback) { CashFlowProjections.create({ year: reqParams.year[index], belongsTo: property.id, cash: reqParams.cash[index], ...}) .exec(function(err, cashflows) { callback(err, cashflows); }); }); })(index); } 

如果你这样做,实际上有两个独立的variables叫做index

  • 原始的,在你的原始脚本的第5行声明,并用于行,也在})(index); 。 它的值从0开始,每次经过循环时递增。
  • function(index)处声明的新的内部function(index) 。 这覆盖原来的,但只在函数定义。 实际上,这实际上是几个独立的作用域:每次它通过循环时,它创build一个新的(匿名)函数并调用它,调用函数创build作用域。 它的值被设置为循环运行时的外部index ,在此之后永远不会改变,并且在async.parallel运行任务时使用。

所以,如果你喜欢,你可以重命名两个variables之一,以避免混淆。