按顺序触发异步事件

时间:2015-05-16 10:43:06

标签: javascript jquery ajax

我有几个异步的事件,因为它们涉及ajax调用,比如这个

$base.on('submit', '.form', function(){
    $.ajax({url: this.action, data: $(this).serialize(), type: 'POST'}).done(function(response){
        $("#container").append(response);
    });
    return false;    
});

$base.on("click", "#addNew", function(){
    $("#editArea").load($(this).data('href'));
    return false;
});

我想要实现的是同步触发第一个form.submit()事件,并且仅在它完成触发$("#addNew").click()事件之后,然后执行其他操作。我试过像:

$.when($form.trigger('submit'))
    .then(function(){$new.trigger('click')})
    .done(function(){
        //do something
    });

但它似乎不起作用。此外,我必须注意,我不能使用triggerHandler因为这些事件被委派(它们触发插入ajax的内容)。 当然,我可以通过async: true使这些ajax调用同步,但我希望尽可能避免修改现有代码。有没有其他方法可以做这些事情?

1 个答案:

答案 0 :(得分:1)

如果您想在不更改现有submitclick事件处理程序的情况下执行此操作,我担心这将是困难和令人讨厌的。那些AJAX请求是这些事件处理程序的副作用,因此您必须以某种方式监视和修改传出的AJAX请求以挂钩您的额外处理。或者,您可以监控#container#editArea进行DOM更改...

最简单的解决方案是将这些事件处理程序作为单独的函数提取并让它们返回一个promise。这样,呼叫者可以随心所欲地连接这些承诺。

function submitForm($form){
    return $.ajax({url: $form.prop('action'), data: $form.serialize(), type: 'POST'})
        .then(function(response){
            $("#container").append(response);
        });
});

function addNew($new){
    // Note: using $.get and $.html instead, since $.load doesn't return a promise
    return $.get($new.data('href'))
        .then(function(response){
            $("#editArea").html(response);
        });
});

在您的事件处理程序中,您可以简单地忽略返回的promise。

$base.on('submit', '.form', function(){
    submitForm($(this));
});

$base.on("click", "#addNew", function(){
    addNew($(this));
});

然而,对于你的序列,你可以链接返回的promises。

submitForm($form)
    .then(function(){addNew($new)})
    .then(function(){
        //do something
    });