下面的代码,在运行时有效,但似乎它不按顺序附加帖子(有时候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()
函数。这三个都有相同的结果,在运行时它们不会按顺序附加文档(所以当我点击刷新时,标题的顺序不同)。任何想法为什么会发生这种情况并找到解决办法?
答案 0 :(得分:6)
$.ajax
是一个异步函数,意味着你的所有$.async
函数都是并行发生的,并且会按照它们完成的顺序附加到正文中(这显然会根据函数的大小而变化)他们提取的文件和一般的网络延迟。)
您可能希望查看async.js库,它允许您并行运行AJAX调用,然后在完成所有调用后执行回调。您需要使用async.parallel
函数,该函数将每个AJAX调用的结果作为数组传递给最终回调。
答案 1 :(得分:3)
这正是jQuery的$.when
和deferred.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] );
});
});