2015-05-16 2 views
-1

У меня есть несколько событий, которые являются асинхронными, так как они связаны с 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 содержимом). Конечно, я мог бы сделать эти ajax-вызовы синхронными через async: true, но я хотел бы избежать модификации существующего кода как можно больше. Есть ли другой способ делать такие вещи?

+0

Dowvote без комментариев не идет. – dbf

+0

Дорогой, нормальная ли строка '$ ('# container')' begin with 'и заканчивается на?? –

+0

Это не так, но это не мой правильный код (я пишу в CoffeeScript), я написал его вручную, поэтому я сделал некоторые опечатки на этом пути. – Eternal1

ответ

1

Боюсь, что это будет сложно и неприятно, если вы захотите сделать это, не изменяя существующие обработчики событий submit и click. Те AJAX-запросы - это побочные эффекты этих обработчиков событий, поэтому вам нужно как-то контролировать и изменять исходящие запросы AJAX, чтобы подключить дополнительное управление. Или, возможно, вы могли бы контролировать #container и #editArea для изменений DOM ...

Простейшим решением было бы извлечь эти обработчики событий в виде отдельных функций и вернуть им обещание. Таким образом, вызывающий может подключить эти обещания в любом случае.

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); 
     }); 
}); 

В вашем обработчике событий вы можете просто игнорировать возвращенное обещание.

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

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

Для вашей последовательности, однако, вы можете связать полученные обещания.

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

Этот метод работал просто отлично, спасибо. Кроме того, это дало мне отличный повод для рефакторинга этого кода на несколько классов «CoffeeScript», что сделало его намного лучше, чем приятный бонус (: – Eternal1