[英]Weird index issue in Backbone click event callback
I have this code, it's independent and isolated. 我有这段代码,它是独立和隔离的。 The problem I am having is that the index i is starting at 1 instead of starting at 0. I have no idea why this could be, and doesn't seem to have anything to do with the closure that I am pushing into the deletes array...but I can't be sure, no idea what the issue is. 我遇到的问题是索引i从1开始而不是从0开始。我不知道为什么会这样,而且似乎与我推入deletes数组的闭包无关。 ...但是我不确定,不知道问题是什么。
onClickResetAll: function (event) {
event.preventDefault();
var deletes = [];
Object.keys(collections).forEach(function (key) {
if (collections.hasOwnProperty(key)) {
var coll = collections[key];
for (var i = 0; i < coll.models.length; i++) {
deletes.push(function (callback) {
var index = i; //i starts at 1, not 0 !!!
coll.models[index].deleteModel(function (err, resp, x) {
console.log(err, resp, x);
if(err){
callback(err);
}
else{
callback(null,null);
}
});
});
}
}
});
async.parallel(deletes,function(err,results){
Backbone.Events.trigger('bootRouter', '+refreshCurrentPage');
});
}, //end of onClickResetAll callback function
//end
The problem isn't really that i
starts at one, the problem is that i
will be coll.models.length
for every function in deletes
. 这个问题是不是真正的i
从1开始,问题是, i
会coll.models.length
在每个函数deletes
。 Why would that be? 为什么会这样呢? Well, each function is sharing the same i
and i
won't be evaluated until the functions inside deletes
are actually called. 好吧,每个函数都共享相同的i
,直到真正调用deletes
内部的函数, i
才会被评估。
The solution is to force i
to be evaluated when it has the value you want (ie evaluated i
when you're building the callback function). 解决的办法是逼i
到时候有你想要的值(即评估来评估i
,当你正在构建的回调函数)。 There are various solutions and they're all variations on the "wrap it in a function to break the reference" theme: 有多种解决方案,它们都是“将其包装为打破引用的函数”主题的变体:
Use an iterator with a callback function instead of a plain for
loop: 使用带有回调函数的迭代器,而不要使用普通的for
循环:
coll.each(function(model, i) { // `model` is the model from the collection, `i` is the loop index. });
You can use each
here because Backbone collections have a bunch of Underscore functions built in . 您可以在此处使用each
,因为Backbone 集合具有内置的一堆Underscore函数 。
Wrap the loop body in an SIF: 将循环体包裹在SIF中:
for(var i = 0; i < coll.models.length; ++i) (function(i) { //... })(i);
Use a separate function to build your functions: 使用单独的函数来构建函数:
function make_deleter(coll, i) { return function(callback) { coll.models[i].deletedModel(function(err, resp, x) { //... } } } //... for(var i = 0; i < coll.models.length; ++i) deletes.push(make_deleter(coll, i));
They all do pretty much the same thing: add an extra function call into the mix to force i
to be evaluated (rather than just referenced) on each iteration of the loop. 它们几乎都做同样的事情:向循环中添加一个额外的函数调用,以强制在循环的每次迭代中对i
进行评估(而不只是引用)。
In a Backbone situation, 1 would probably be the most natural and you wouldn't even need your troublesome i
with that approach. 在骨干网的情况下,1很可能是最自然,你甚至不会需要你的麻烦, i
用这种方法。
another solution to this is using async.each or async.eachSeries instead of async.parallel. 另一个解决方案是使用async.each或async.eachSeries而不是async.parallel。 using the first 2 avoids pushing to an array of functions altogether. 使用前两个避免完全推送到一组函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.