简体   繁体   English

骨干点击事件回调中的奇怪索引问题

[英]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开始,问题是, icoll.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: 有多种解决方案,它们都是“将其包装为打破引用的函数”主题的变体:

  1. 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函数

  2. Wrap the loop body in an SIF: 将循环体包裹在SIF中:

     for(var i = 0; i < coll.models.length; ++i) (function(i) { //... })(i); 
  3. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM