Javascript结束For Loop链一个回调

时间:2014-04-25 06:22:01

标签: javascript jquery for-loop jquery-deferred

如何知道For循环何时完成迭代并附加回调。

这是函数中许多循环的示例循环,它将记录插入 indexedDB

 if (Object.hasOwnProperty("Books")) {
            for (var i = 0, j = Object["Books"].length; i < j; i++) {
                server.Book.add({
                    title: Object["Books"][i].Cat,
                    content: Object["Books"][i]
                });
            }
        }

我需要能够知道每个if语句循环何时完成然后附加回调。所有循环都是异步触发的,我需要在所有循环完成时运行function_final(),而不是在它们被触发时运行。

修改

到目前为止我尝试过:

 InsertDB = {
  addBook: function(Object) {
    return $.Deferred(function() {
        var self = this;
        setTimeout(function() {
        if (Object.hasOwnProperty("Book")) {                
            for (var i = 0, j = Object["Book"].length; i < j; i++) {
                server.Book.add({
                    title: Object["Book"][i].id,
                    content: Object["Book"][i]
                });
            }
            self.resolve();
        }
        }, 200);
   });  
 },
  addMagaz: function(Object) {
  return $.Deferred(function() {
        var self = this;
        setTimeout(function() {

        if (Object.hasOwnProperty("Magaz")) {
            for (var i = 0, j = Object["Magaz"].length; i < j; i++) {                  
                server.Magaz.add({
                    content: Object["Magaz"][i]
                });
            }
            self.resolve();
        }
        }, 2000);
   });  
},
addHgh: function(Object) {
    return $.Deferred(function() {
        var self = this;
        setTimeout(function() {

        if (Object.hasOwnProperty("MYTVhighlights")) {
            for (var i = 0, j = Object["MYTVhighlights"].length; i < j; i++) {
                server.MYTVhighlights.add({
                    content: Object["MYTVhighlights"][i]
                });
            }
            self.resolve();
         }
        }, 200);
   });  

  }, ect...

然后是AJAX成功回调:

 success: function(data){
 var Object = $.parseJSON(data);

    $.when(InsertDB.addBook(Object),
    InsertDB.addMagaz(Object),
    InsertDB.addUser(Object),
    InsertDB.addArticles(Object),
    InsertDB.addHgh(Object),
    InsertDB.addSomeC(Object),
    InsertDB.addOtherC(Object)).done(final_func);

 function final_func() {
    window.location = 'page.html';
  }

这里在循环结束之前触发了final_func ..

由于

4 个答案:

答案 0 :(得分:1)

您可以使用JavaScript closures,就像这样:

if (Object.hasOwnProperty("Books")) {
    for (var i = 0, j = Object["Books"].length; i < j; i++) {
        (function(currentBook)
            server.Book.add({
                title: currentBook.Cat,
                content: currentBook
            });
        )(Object["Books"][i]);
    }

    function_final();
}

有关closures的详情,请参阅here

答案 1 :(得分:0)

在功能

时使用jquery
$.when( function1 , function2 )
  .then( myFunc, myFailure );

答案 2 :(得分:0)

我在纯JS中写这样的东西,把它当作伪代码:

var totalForLoopsCount = 3; //Predict for loops count here
var forLoopsFinished = 0;

function finalFunction()
{
    alert('All done!');
}

function forLoopFinished()
{
    forLoopsFinished++;
    if(forLoopsFinished == totalForLoopsCount)
    {
        finalFunction();
    }
}

var length = 10; //The length of your array which you're iterating trough

for(var i=0;i<length;i++)
{
    //Do anything        

    if(i == length-1)
    {
        forLoopFinished();
    }
}

for(var i=0;i<length;i++)
{
    //Do anything        

    if(i == length-1)
    {
        forLoopFinished();
    }
}

for(var i=0;i<length;i++)
{
    //Do anything    

    if(i == length-1)
    {
        forLoopFinished();
    }
}

答案 3 :(得分:0)

由于您已经说过server.Book.add()是异步的,因此您需要一种方法来了解该异步操作何时完成,然后您可以使用该方法构建一个系统以了解所有这些操作何时完成。因此,关键问题(我之前已作为评论提出并且您没有回复)是如何知道server.Book.add()何时实际完成的。如果你正在使用indexedDB,那么在该函数内的某个地方,可能有一个请求对象具有onsuccessonerror方法,它们将告诉您何时该特定操作是完成并且信息需要以某种方式浮出水面server.Book.add(),作为完成回调或作为返回的承诺(这两个选项是$.ajax()如何操作它的异步行为。

假设server.Book.add()返回一个在异步.add()操作完成时被解析或拒绝的promise对象。如果是这种情况,那么您可以监视循环中所有操作的完成情况,如下所示:

    if (obj.hasOwnProperty("Books")) {
        var promises = [], p;

        for (var i = 0, j = obj["Books"].length; i < j; i++) {
            p = server.Book.add({
                title: obj["Books"][i].Cat,
                content: obj["Books"][i]
            });
            promises.push(p);
        }
        $.when.apply($, promises).done(function() {
            // this is executed when all the promises returned by
            // server.Book.add() have been resolved (e.g. completed)
        }).error(function() {
            // this is executed if any of the server.Book.add() calls
            // had an error
        });
    }

我们假设代替server.Book.add()返回一个承诺,它会针对successerror条件进行一些回调。然后,我们可以编写如下代码:

    if (obj.hasOwnProperty("Books")) {
        var promises = [], p;

        for (var i = 0, j = obj["Books"].length; i < j; i++) {
            (function() {
                var d = $.Deferred();
                server.Book.add({
                    title: obj["Books"][i].Cat,
                    content: obj["Books"][i],
                    success: function() {
                        var args = Array.prototype.slice.call(arguments, 0);
                        d.resolve.apply(d, args);
                    },
                    error: function() {
                        var args = Array.prototype.slice.call(arguments, 0);
                        d.reject.apply(d, args);
                    }
                });
                promises.push(d.promise());
            })();
        }
        $.when.apply($, promises).done(function() {
            // this is executed when all the promises returned by
            // server.Book.add() have been resolved (e.g. completed)
        }).error(function() {
            // this is executed if any of the server.Book.add() calls
            // had an error
        });
    }

所以,既然你还没有透露server.Book.add()实际上是如何表明它自己的完成,我就不能说这些代码块中的任何一个都是按原样工作的。这是为了说明一旦您知道server.Book.add()在完成时如何通信,您将如何解决此问题。

承诺/延迟在任何方面都不是魔术。除非该操作在承诺上调用.resolve().reject(),否则他们不知道操作何时完成。因此,为了使用promises,你的异步操作必须参与使用promises,或者你必须对普通完成回调的承诺(正如我在第二个代码块中所做的那样)。

仅供参考,我还将您的Object变量更改为obj,因为在javascript语言中定义与内置Object冲突的名为Object的变量是错误的实践。