簡體   English   中英

For Loop鏈的Java語言結尾回調

[英]Javascript end of For Loop chain a callback

您如何知道何時完成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在循環結束之前被觸發。

謝謝

您可以使用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更多信息,請參見此處

使用jQuery時的功能

$.when( function1 , function2 )
  .then( myFunc, myFailure );

我會在純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();
    }
}

既然您已經說過server.Book.add()是異步的,那么您將需要一種知道異步操作何時完成的方法,然后可以使用該方法構建一個系統來了解所有這些操作何時完成。 因此,關鍵的問題(我已經在前面提過評論,您尚未回答)是如何知道server.Book.add()何時完成。 如果您使用的是indexedDB ,則在該函數內部的某個位置,可能有一個請求對象,該對象具有onsuccessonerror方法,這些方法將告訴您何時執行特定操作,並且需要將這些信息浮出水面到server.Book.add()以某種方式server.Book.add()作為完成回調或作為返回的Promise(這兩個選項是$.ajax()如何對其異步行為進行操作)。

假設server.Book.add()返回一個promise對象,當異步.add()操作完成時,該對象將被解析或拒絕。 如果是這種情況,那么您可以像這樣監視循環中所有操作的完成情況:

    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()在完成后如何通信時如何解決此問題。

承諾/延期絕不是魔術。 他們不知道操作何時完成,除非該操作在promise上調用.resolve().reject() 因此,為了使用promise,您的異步操作必須參與使用promise,或者您必須將promise填充到普通的完成回調中(就像我在第二個代碼塊中所做的那樣)。

僅供參考,我也改變你的Object變量obj因為定義一個變量命名的Object ,與內置的沖突Object的JavaScript語言是一種不好的做法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM