【问题标题】:Do action after another ajax function ends在另一个 ajax 函数结束后执行操作
【发布时间】:2023-03-03 15:49:02
【问题描述】:

我正在为此寻找解决方案: 我有一个更新应用程序中表格内容的函数。

function prev_update(cli_id){
    $("#list").empty();
    $("#list").append("<tr><td colspan=11><img src='images/loading.gif' alt=loading title=loading /></td></tr>");
    $.ajax({
        type        : 'POST',
        url         : 'json/get.php?t=2&id='+cli_id, 
        dataType    : 'json',
        encode      : true
    })
    .done(function(data) {
        $("#list").empty();
        if ((data)["prev_list"]) {  
            $.each((data)["prev_list"], function( i, val ) {
                $( "#list" ).append(val);
            });
            $("#edit").hide("slow");
        } else {
            $("#list").append("<tr><td colspan=11>&nbsp;</td></tr>");                       
        }
    });
};

在另一个函数中,我正在更新表格的一行,当我完成编辑表格的一行的内容时,我启动了一个类似的函数,但在 .done 行中,我调用了 prev_update 函数,完成后我必须在更新的表格内容中按下一个按钮,以查看修改... 代码如下:

$("#prev_mod").on("click",(function( event ) {
     $('#loading_img').css('display','inline');
     header_print();
     $.ajax({
         type       : 'POST',
         url        : 'json/post.php?mod='+$('#prev_id').val(),
         data       : $("#form_sog").serialize(),
         dataType   : 'json',
         encode : true
   })
   .done(function(data) {
        if ((data)["success"]===false) {    
            $('#form_edit').hide('slow');
            prev_update();
            $('#edit_'+$('#prev_id').val()).click();
        });
   });
}));

我必须等待 prev_update() 函数结束然后单击按钮,因为该按钮位于正在更新的表中。 我也尝试使用延迟对象,但它不起作用(可能是我的错误)。 我无法编辑函数 prev_update,因为它已被其他函数使用。

【问题讨论】:

  • 当你说“prev_update() 函数结束”时,你到底是什么意思?你的意思是它里面的所有动画都完成了,还是你的意思是它只是运行并完成了它开始的工作?而且,既然prev_update() 无休止地调用自己,你怎么不会在这里陷入无限循环。
  • 我发布的第二个代码来自另一个函数。当我说函数结束时,我的意思是函数已经完成了它开始的所有过程(ajax 请求和其他动画)

标签: javascript jquery ajax jquery-deferred


【解决方案1】:

您可以使用.then 代替.done 来组织您的代码。这是因为.then 可以链接

未测试,但可以这样

function prev_update(cli_id){
    $("#list").empty();
    $("#list").append("<tr><td colspan=11><img src='images/loading.gif' alt=loading title=loading /></td></tr>");
    $.ajax({
        type        : 'POST',
        url         : 'json/get.php?t=2&id='+cli_id, 
        dataType    : 'json',
        encode      : true
    })
    .then(function(data) {
        $("#list").empty();
        // rest of code
    }).then(function(data) {
        if ((data)["success"]===false) {    
            // rest of code
        };
   });

【讨论】:

  • data 不会传递给第二个链接的 .then() 处理程序,除非您从前一个处理程序返回它。
  • @jfriend00 是对的,我也觉得这可能会导致执行永无止境,因为在第二个.then 中再次引用了prev_update,这将导致第一个.then 的执行等等
  • 函数prev_update可以被其他函数使用,所以我不能修改prev_update函数,但我必须使用另一个函数。抱歉,如果我的问题不清楚...
【解决方案2】:

如果您想知道prev_update() 中的所有内容何时完成,您必须对其进行修改以跟踪其中的异步操作并返回一个承诺。然后,调用者可以使用返回的承诺来知道事情何时完成。

所以,在prev_update() 内部,两个异步操作是ajax 调用和.hide() 动画。隐藏动画发生在 ajax 操作的完成处理程序内部。因此,如果您将.done() 更改为.then(),我们可以将这些promise 链接在一起并返回一个promise,该promise 将在一切完成时告诉调用者。

jQuery 有一个.promise() 方法,它可以为我们提供一个链接到任何 jQuery 动画的 Promise,因此如果我们只是获得动画的 Promise,我们可以返回它,它会链接到父 Promise。如果没有动画,那么我们可以不返回任何内容,promise 链将继续。

这根本不会改变 prev_update() 的功能 - 它只是返回一个跟踪其完成的承诺(当您之前没有返回任何内容时)。

可以这样工作:

function prev_update(cli_id){
    $("#list").empty();
    $("#list").append("<tr><td colspan=11><img src='images/loading.gif' alt=loading title=loading /></td></tr>");
    return $.ajax({
        type        : 'POST',
        url         : 'json/get.php?t=2&id='+cli_id, 
        dataType    : 'json',
        encode      : true
    }).then(function(data) {
        var p;
        $("#list").empty();
        if ((data)["prev_list"]) {  
            $.each((data)["prev_list"], function( i, val ) {
                $( "#list" ).append(val);
            });
            p = $("#edit").hide("slow").promise();
        } else {
            $("#list").append("<tr><td colspan=11>&nbsp;</td></tr>");                       
        }
        // return promise if there was one
        return p;
    });
};

那么,您可以在其他代码中使用它,如下所示:

$("#prev_mod").on("click",(function( event ) {
     $('#loading_img').css('display','inline');
     header_print();
     $.ajax({
         type       : 'POST',
         url        : 'json/post.php?mod='+$('#prev_id').val(),
         data       : $("#form_sog").serialize(),
         dataType   : 'json',
         encode : true
   }).then(function(data) {
        if ((data)["success"]===false) {    
            $('#form_edit').hide('slow');
            prev_update().then(function() {
                // apply click when everything in prev_update() is done
                $('#edit_'+$('#prev_id').val()).click();
            });
        });
   });
}));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-14
    • 2017-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多