2013-03-09 39 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