迭代数组不按顺序执行操作?

时间:2013-03-09 19:46:17

标签: javascript html arrays

下面的代码,在运行时有效,但似乎它不按顺序附加帖子(有时候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的_.each()函数。这三个都有相同的结果,在运行时它们不会按顺序附加文档(所以当我点击刷新时,标题的顺序不同)。任何想法为什么会发生这种情况并找到解决办法?

2 个答案:

答案 0 :(得分:6)

$.ajax是一个异步函数,意味着你的所有$.async函数都是并行发生的,并且会按照它们完成的顺序附加到正文中(这显然会根据函数的大小而变化)他们提取的文件和一般的网络延迟。)

您可能希望查看async.js库,它允许您并行运行AJAX调用,然后在完成所有调用后执行回调。您需要使用async.parallel函数,该函数将每个AJAX调用的结果作为数组传递给最终回调。

答案 1 :(得分: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的回调函数只有在promises全部解析后才会运行。因此,即使page2的请求可能在page1之前完成,我们也不担心。在完成所有请求之前,我们不会调用我们的代码。

在您的特定情况下,异步请求的数量未知且不同,您可能会发现使用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] );
    });
});