在另一个ajax函数结束后执行操作

时间:2016-11-30 07:02:17

标签: javascript jquery ajax jquery-deferred

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

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函数,因为它被其他函数使用。

2 个答案:

答案 0 :(得分:2)

您可以使用.done来组织代码,而不是.then。这是因为.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
        };
   });

答案 1 :(得分:1)

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

因此,在prev_update()内,两个异步操作是ajax调用和.hide()动画。隐藏动画发生在ajax操作的完成处理程序内部。因此,如果您将.done()更改为.then(),我们可以将这些承诺链接在一起并返回单个承诺,以便在完成所有操作后通知调用方。

jQuery有一个.promise()方法,它将为我们提供一个链接到任何jQuery动画的承诺,所以如果我们得到动画的承诺,我们可以返回它,它将链接到父承诺。如果没有动画,那么我们就可以不返回任何内容,并且承诺链将继续。

这根本不会改变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();
            });
        });
   });
}));