2013-03-09 73 views
1

下面的代碼,運行工作,但現在看來似乎並不會自動追加的職位,以便在(有時post_2是第一和post_4秒):對數組進行迭代不會按順序執行任何操作?

var posts = [ 
    "post_1.md", 
    "post_2.md", 
    "post_3.md", 
    "post_4.md", 
    "post_5.md", 
    "post_6.md", 
    "post_7.md"]; 

for (var i in posts) { 
    $.ajax({ 
     url: "posts/" + posts[i], 
     context: document.body, 
     success: function (mdText) { 
      var converter = new Showdown.converter(); 
      var htmlText = converter.makeHtml(mdText); 
      $("body").append(htmlText); 
     } 
    }); 
} 

它遍歷數組中的元素,爲每個元素下載一個Markdown文檔,將其轉換爲HTML,並將其附加到主體。我嘗試了一個簡單的for循環以及Underscore的​​函數。所有三個都有相同的結果,運行時它們不按順序附加文檔(所以當我點擊刷新時,標題的順序不同)。任何想法,爲什麼會發生這種情況和解決辦法?

回答

6

$.ajax是一個異步功能,這意味着所有的$.async功能都發生在平行和將追加到身體的秩序,他們完成(這可以根據他們獲取的文件和一般網絡的規模明顯變化延遲)。

您可能希望查看async.js庫,該庫允許您並行運行AJAX調用,然後在完成所有調用時執行回調。你想要使用async.parallel函數,它將每個AJAX調用的結果作爲數組傳遞給最終回調函數。

+0

謝謝。正是我在找的東西;不知道我怎麼沒有注意到這一點。 – raf 2013-03-09 19:53:45

+0

@RafalChmiel很高興這是你要找的東西,如果你不介意的話,請將它標記爲已接受的答案:) – 2013-03-09 19:57:29

+0

當然,當我查看[documentation]時,我簡單地設置了'async:false', (http://api.jquery.com/jQuery.ajax/)使這個同步。 – raf 2013-03-09 20:02:03

3

這恰恰是jQuery的$.whendeferred.done的意思。你傳遞了一系列延遲(jQuery的$.ajax返回延遲),當他們的承諾解決時,你可以單獨處理它們中的每一個。下面是從jQuery的API文檔本身的修改示例:

$.when($.ajax("/page1.php"), $.ajax("/page2.php")).done(function(a1, a2) { 
    /* a1 and a2 are arguments resolved for the page1 and page2 ajax requests */ 
}); 

時的承諾已全部解決傳入.done回調函數將只跑了。所以即使第2頁的請求可能在第1頁之前完成,我們並不擔心。我們的代碼在所有請求完成之前不會被調用。

你的具體情況,其中asynchrnous請求的數量是不知道,和而不同,你可能會使用func.apply而不是找到更多的成功:

var reqs = []; 

reqs.push($.ajax("post_1.md"), $.ajax("post_2.md"), $.ajax("post_3.md")); 

$.when.apply(this, reqs).done(function() { 
    $.each(arguments, function (index, value) { 
     console.log(value[0]); 
    }); 
}); 
+0

謝謝,那我怎麼把這個放到我的代碼的上下文中呢? – raf 2013-03-09 20:32:22

+1

@RafalChmiel我已經更新了上面的代碼,以更接近你的情況。 – Sampson 2013-03-10 15:33:06

+0

謝謝,我會試試看。 – raf 2013-03-10 18:21:19