把手多个ajax请求和模板结果

时间:2015-01-30 21:08:11

标签: jquery ajax api loops handlebars.js

这实际上是一个单独的线程问题以及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。

感谢。

2 个答案:

答案 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.");
});