如何迭代创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
的副本,而不会受到原始index
的index++
的影响。 喜欢这个:
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之一,以避免混淆。