这实际上是一个单独的线程问题以及javascript如何在本地运行。但是,我还没有想出办法绕过这个。
我有一个标准的ajax请求:
$.ajax({
url: url,
cache: false,
success: function (response) {
// send to handlebars template
resultsPlaceholder.html(template(response));
});
});
以上工作正常。
我需要做的是实际获取该结果,循环并运行另一个api请求并将其添加到原始数据中:
$.ajax({
url: url,
cache: false,
success: function (response) {
$.each(response.results, function(key, value) {
$.ajax({
type: "GET",
url: url + "?id=" + response.results[key].id,
dataType: 'jsonp',
}).done(function(return_data) {
response.results[key].details = return_data.info;
});
});
resultsPlaceholder.html(template(response));
});
});
显而易见的问题是,在循环中完成所有ajax请求之前,发送到把手模板的数据正在发生。
这不是车把特有的。我只是想知道避免这种情况的惯例是什么。我不想使用setTimeout,这似乎是hackish。
感谢。
答案 0 :(得分:2)
详细说明Ryley的评论,这样的事情应该有效:
var promises = [];
$.getJSON(url).done(function(response) {
$.each(response.results, function(key, val) {
promises.push($.get(url, {id: val.id}));
});
});
//When all of the promises are resolved
$.when.apply($, promises).done(function() {
var responses = Array.prototype.slice.call(arguments);
//Do what you need to do with responses
//And then load your handlebars template
resultsPlaceholder.html(template(responses));
});
说明:
这只是循环你的初始AJAX响应并创建一个promises数组。然后你可以使用$.when.apply()
,因为(我假设)你不知道第一个回复中会有多少项。
祝你好运:)
答案 1 :(得分:1)
除了@Eclecticist's answer之外,还有一个更加精简的版本,强调可读性:
// just wrap up the cumbersome $.when.apply(...)
$.whenAll = function (promises) {
return $.when.apply($, $.makeArray(promises));
};
function renderResults($target, template) {
var pendingRequests,
url; // = your url
$.getJSON(url).done(function(response) {
pendingRequests = $.map(response.results, function (item) {
return $.get(url, {id: item.id});
});
});
return $.whenAll(pendingRequests).done(function() {
var html = template($.makeArray(arguments));
$target.html(html);
});
}
由于renderResults
本身会返回一个承诺,您可以执行
renderResults( $("#target"), niceTemplate ).done(function () {
alert ("All " + arguments.length + " results finished.");
});