【问题标题】:method is executing before ajax call getting completed方法在 ajax 调用完成之前执行
【发布时间】:2014-08-15 10:52:24
【问题描述】:

我试图在所有 ajax 调用完成后调用一个方法,但由于某种原因,方法 ID 在其中一个 ajax 调用完成之前被触发。我试图将方法保留在 ajax 完整部分并使用 $.when() 和 async:false 但我得到了相同的结果。不知道是不是因为我用的是jsonp?

我的 jquery 版本是 1.11.0

下面是我的代码

function getBBTrending() {
    bbProductD = [];
    jQuery.ajax({
        type: "GET",
        url: "crazycalls/getbbtrending.php",
        // cache must be true
        cache: true,
        crossDomain: true,
        success: function (data) {
            bbTrending = data.results;
            for (var i = 0; i < 4; i++) {
                getProductdetails(bbTrending[i].productLink);
            }
        },
        dataType: 'json'
    });
}

function getProductdetails(pLink) {
    jQuery.ajax({
        type: "GET",
        url: pLink,
        // cache must be true
        cache: true,
        crossDomain: true,
        success: function (data) {
            pushArray(bbProductD, data);
        },
        dataType: 'jsonp'
    });
}




function pushArray(array1,data1)
{
    array1.push(data1);
}

// this function is executing before pushArray(array1,data1)
jQuery( document ).ajaxStop(function() {
 displayProducts(bbProductD);
})
function displayProducts(bbProductD)
{
    jQuery("#bbButtongroup").show();
    var rProducts = bbProductD; 
    var rating;
    var html = ['<div class="row">']
    for (var i = 0; i < rProducts.length; i++)
    {
           var entry = rProducts[i];
           var title = entry.name
           var Tnail = entry.image;
           var sPrice = entry.salePrice;
           var rPrice = entry.regularPrice;
         var hcode = '<div class="col-sm-6 col-md-4"><div class="thumbnail"><img style="height: 200px; width: 100%; display: block;" src=\" '+ Tnail + '\" alt="..."><div class="caption"><h3 style="font-size: 14px;">'+ title +'</h3><p><span class="label label-info"> Regular Price : '+ rPrice +'</span></p><p><span style="float: right;" class="label label-info">Sale Price :'+ sPrice +'</span></p><p><a href=\"' + entry.url + '\" class="btn btn-primary" role="button">Buy</a><a href="#" class="btn btn-default" role="button">View</a></p></div></div></div>';
         html.push(hcode);
     }
     html.push('</div>');
     document.getElementById('pContainer').innerHTML = html.join('');
}

这就是我使用 $.when 添加的方式

jQuery.when( { getBBTrending(),getProductdetails()}).done(function() {
   displayProducts(bbProductD);
});

有什么建议吗?

【问题讨论】:

  • 您不能使用带有 JSON 的 async: false。但是什么被触发得太早了?为什么不将所有代码放在一个 AJAX 调用中?
  • 不要依赖 ajaxStop 来完成这种工作。你不能把displayProducts(bbProductD); 电话放在pushArray(bbProductD,data); 电话之后吗?
  • 展示你如何尝试使用$.when,它应该做你想做的事
  • @Putvande 我尝试在 getBBTrending() 中的 forloop 之后将所有代码放入 ajax 调用中,但结果仍然相同。
  • @Volune 我正在使用所有产品列表构建我的数组,而不是我想调用 displayProducts(bbProductD) ,我不想为每个产品调用 displayProducts(bbProductD)。请参阅我添加了 displayProducts (bbProductD) 在我原来的帖子中

标签: javascript jquery ajax


【解决方案1】:

异步方式,使用async

function getBBTrending() {
    bbProductD = [];
    jQuery.ajax({
        //stuff...
        success: function (data) {
            bbTrending = data.results;
            async.each(bbTrending, function(element, callback){
                getProductdetails(element.productLink, callback);
            }, function(err){
                displayProducts(bbProductD);
            });
        },
    });
}

function getProductdetails(pLink, callback) {
    jQuery.ajax({
        //stuff
        success: function (data) {
            pushArray(bbProductD, data);
            callback(null);
        },
    });
}

promise 方式,使用jQuery.DeferredjQuery.when

function getBBTrending() {
    bbProductD = [];
    jQuery.ajax({
        //stuff...
        success: function (data) {
            bbTrending = data.results;
            var promises = [];
            for (var i = 0; i < bbTrending.length; i++) {
                var promise = getProductdetails(bbTrending[i].productLink);
                promises.push(promise);
            }
            jQuery.when.apply(jQuery, promises).then(function(){
                displayProducts(bbProductD);
            });
        },
    });
}

function getProductdetails(pLink) {
    var promise = jQuery.Deferred();
    jQuery.ajax({
        //stuff
        success: function (data) {
            pushArray(bbProductD, data);
            promise.resolve();
        },
    });
    return promise;
}

肮脏的方式。我不推荐这个解决方案,它有很多缺陷。当您需要执行异步操作以保持代码可维护性时,请尝试使用库。

var queriesCount, finishedQueriesCount;

function getBBTrending() {
    bbProductD = [];
    jQuery.ajax({
        //stuff...
        success: function (data) {
            bbTrending = data.results;
            queriesCount = 0;
            finishedQueriesCount = 0;
            for (var i = 0; i < bbTrending.length; i++) {
                getProductdetails(bbTrending[i].productLink);
            }
        },
    });
}

function getProductdetails(pLink) {
    queriesCount++;
    jQuery.ajax({
        //stuff
        success: function (data) {
            pushArray(bbProductD, data);
            finishedQueriesCount++;
            if(queriesCount == finishedQueriesCount) {
                displayProducts(bbProductD);
            }
        },
    });
}

在每种情况下,我都对//stuff的答案不重要的代码部分表示感谢

警告此答案没有错误处理,如果您有 ajax 错误,它将失败(永远不要调用 displayProducts(bbProductD);)。

【讨论】:

  • 谢谢,承诺方式对我有用,我也会记住这个方法以备将来使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-24
  • 2017-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多