【问题标题】:Nested AJAX Calls using .done使用 .done 的嵌套 AJAX 调用
【发布时间】:2014-05-15 22:12:15
【问题描述】:

我对 AJAX 还很陌生,但是正在从事一个需要 ajax 调用来验证特定值的项目,如果第一个返回预期值,则再进行另一个 ajax 调用。我正在尝试实现 .done/.fail 模型,但找不到阻止两个调用同时发生的方法,而不是在第一次调用完成并成功后。

以下代码将调用 ajaxCall 函数两次,但同时调用,而不是连续调用。我研究了大量代码,包括Nested AJAX CallsjQuery getting rid of nested ajax functions$.when.done callback isn't working,但似乎没有一个适合我的确切情况,或者我只是不理解代码。无论哪种方式,我都无法找到解决方案,非常感谢任何帮助!

var xReturn = ajaxCall("1");    

xReturn.done(function(msg){
    console.log("callback "+msg+" successful");

    // if successful, place second call
    if(parseInt(msg)==1)
        xReturn = ajaxCall("2");    
});


function ajaxCall(mop){
    return $.ajax({
         url: "getItem.php",
         type: "POST",
         data: {code: '<?php echo $code; ?> ', op:mop}
    });
}

似乎 promises 可能是要走的路,但我不知道如何在这种情况下使用它们。提前感谢您提供正确方向的任何指示。

更新:

我进行了一系列不同结果的测试。对于昨晚的最后一次测试,我在ajaxCall("2"); 之后直接放置了另一个console.log(msg); 每次生成的消息总是“1”,这让我相信电话没有正常进行。这个结果告诉我 xReturn.done(function(msg)... 只被调用一次,但我认为它会在每次 ajax 调用时被调用。

有了这些新信息,我今晚将进行额外的测试并报告。
谢谢

【问题讨论】:

  • “看起来 promises 可能是要走的路,但我不知道如何在这种情况下使用它们。” 但你已经在使用承诺。 xReturn 是一个承诺。无论如何,你如何确定你的代码是并行运行的?看起来它应该连续运行。您传递给 .done 的回调仅在第一个 Ajax 完成后执行。
  • 为什么不在这两种情况下都使用.$.ajax 并在第一个success 中调用第二个ajax?
  • 这是一个演示,它显示了 Ajax 调用是按顺序执行的:jsfiddle.net/9fT2e/5.
  • 感谢演示,我可以看到 ajax 调用是按顺序执行的。我稍微更新了小提琴,但希望看到第二次调用 xReturn.done(...) 函数作为 xReturn=ajaxCall(2); 的回调。如何确定第二次通话是否成功? jsfiddle.net/9fT2e/6
  • @Kristofer 见帖子。谢谢。

标签: javascript jquery ajax


【解决方案1】:

您需要将.done() 方法绑定到每个 承诺。 xReturn.done() 将函数绑定到该承诺。

当您执行xReturn = ajaxCall("2"); 时,您替换 xReturn 使用不同的对象。该对象没有绑定.done() 方法。

您需要将.done() 绑定到每个承诺,这不会自动发生。

var xReturn = ajaxCall("1");
// This binds the callback to this *specific* promise    
xReturn.done(ajaxDone);    

function ajaxCall(mop){
    return $.ajax({
         url: "getItem.php",
         type: "POST",
         data: {code: '<?php echo $code; ?> ', op:mop}
    });
}

function ajaxDone(msg){
    console.log("callback "+msg+" successful");

    // if successful, place second call
    if(parseInt(msg)==1){
        xReturn = ajaxCall("2");

        // Bind a callback to this *new* object
        xReturn.done(ajaxDone);
    }
}

【讨论】:

    【解决方案2】:

    有多种方法可以解决这个问题。

    您可以简单地从第一个成功调用第二个 ajax 调用。以下几行内容

    function ajaxCall(mop){
        $.ajax({
             url: "getItem.php",
             type: "POST",
             data: {code: '<?php echo $code; ?> ', op:mop}
        }).done(function(msg) {
            console.log("First call is done. Received data as ", msg);
            if(parseInt(msg)==1) {
                $.ajax({
                    //Repeat Options
                }).done(function(newMsg)) {
                    console.log("We're done");
                };
            }
        });
    }
    

    }

    如果您确实想使用 .done/.fail 模型,可以尝试使用 $.when。 这是一个有效的fiddle,它使用相同的函数进行连续调用。

    function ajaxCall(mop){
        return $.ajax({
                url: "/echo/json/",
                type: "POST",
                data: {
                    json: $.toJSON({data: mop}),
                    delay: Math.floor(Math.random()*4)
                }
        });
    }
    
    $.when(ajaxCall("1")).done(function(data) {
        console.log("Done with first call. About to call second");
            if(data /* and add whatever conditions you need to call the next function */) {
                ajaxCall("2");
            }
    });
    

    【讨论】:

    • $.when(ajaxCall("1")).done() 等价于ajaxCall("1").done()。如果您只将一个参数传递给$.when,则没有理由使用它。您的两个解决方案实际上是相同的。
    • @Felix King:第二个重用了ajaxCall函数,我认为这是OP需要的。
    【解决方案3】:

    这样试试吧。

    ajaxCall("1"); 
    
    function ajaxCall(mop){
    $.post( "getItem.php", {code: '<?php echo $code; ?> ', op:mop})
      .done(function( msg) {
        console.log("callback "+msg+" successful");
        if(parseInt(msg)==1)
            ajaxCall("2"); 
      });
    
    }
    

    您也可以将这些与以前的代码一起使用

      .fail(function() {
        alert( "error" );
      })
      .always(function() {
        alert( "finished" );
    

    【讨论】:

    • 为什么 OP 应该尝试这个?他们的代码有什么问题?
    • 他问这个有什么不对吗???。你是编辑它的人
    • “他为什么问这个问题”这就是我想要找出的。既然你回答了这个问题,我希望你能解释一下。
    【解决方案4】:

    怎么样:

    var xReturn1 = ajaxCall("1"),
        xReturn2 = ajaxCall("2");
    
    $.when(xReturn1, xReturn2).done(function( a1, a2 ) {
        var data1 = a1[0], data2 = a2[0];
        console.log("Both done");
    });
    

    【讨论】:

    • 好吧,这肯定会并行而不是顺序运行代码(据我了解,这是 OP 想要的)。
    猜你喜欢
    • 1970-01-01
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    • 2013-11-29
    • 2023-04-08
    • 2011-08-09
    • 1970-01-01
    • 2017-12-17
    相关资源
    最近更新 更多