[英]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
,則在該函數內部的某個位置,可能有一個請求對象,該對象具有onsuccess
和onerror
方法,這些方法將告訴您何時執行特定操作,並且需要將這些信息浮出水面到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()
,而是有幾個success
和error
條件的回調。 然后,我們可以編寫如下代碼:
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.