2013-06-25 1 views
0

Я видел .when() и .then(), которые использовались непосредственно с вызовами .ajax в jquery, чтобы задержать выполнение функции обратного вызова до тех пор, пока не будет выполнена ajax. У меня возникают проблемы с тем же, что и для функций, которые сами по себе не являются аякс-вызовами, но содержат функцию ajax. У меня есть следующий фрагмент коды:Как использовать .when() с функцией, содержащей вызов ajax?

$(function() { 

    $('.document').on('click', '.ajax', ajaxFunction); 

}); 

function ajaxFunction(e) { 
     e.preventDefault(); 

     // ajax request 
     $.ajax({ 
      async: true, 
      cache: false, 
      type: 'post', 
      url: '/echo/html/', 
      data: { 
       html: '<p>This is echoed the response in HTML format</p>', 
       delay: 1 
      }, 
      dataType: 'html', 
      beforeSend: function() { 
       console.log('Fired prior to the request'); 
      }, 
      success: function(data) { 
       console.log('Fired when the request is successfull'); 
       $('.document').append(data); 
      }, 
      complete: function() { 
       console.log('Fired when the request is complete'); 
      } 


     }); 

     console.log('hello world!'); 
    } 

function defferedFunction(d){ 
    $.when(ajaxFunction(e)).then(alert('hi mom!')) 
} 

Моя цель состояла в том, чтобы стрелять предупреждение («привет мамы!»), Когда содержимое функции ajaxFunction было полным, т.е. когда Аякс был сделан и «привет Мир!' зашел на консоль. Однако предупреждение никогда не появляется.

Проблема, насколько я могу судить, заключается в том, что функция контейнера фактически не возвращает обещание, и поэтому раздел .then() никогда не срабатывает. Как я могу изменить этот код, чтобы вернуть обещание, когда весь внутренний код, включая ajax, закончен?

Я бы предпочел продолжить использование шаблона .when()/.then() вместо того, чтобы вручную включать обратный вызов в ajaxFunction.

скрипку приведенного выше примера here.

ответ

0

Я понял, что я могу сделать это, создав отложенное событие для всей функции, отложенное событие для не-АЯКСА поведения, что я хочу, чтобы захватить, решение второго отложенного события после того как материал не-ajax будет выполнен, а затем с помощью $.when(), чтобы зафиксировать, когда и отложенный объект, возвращенный вызовом ajax, разрешен, и когда отложенный объект, который я создал для материала, отличного от ajax, выполняется, а затем с использованием .then() разрешить отложенный объект для всей функции.

Похоже, что это, все вместе взятые:

$(function() { 

    $('.document').on('click', '.ajax', defferedFunction); 

}); 

function ajaxFunction(e) { 
     e.preventDefault(); 

     // ajax request 
     var ajaxDeferred = $.ajax({ 
      async: true, 
      cache: false, 
      type: 'post', 
      url: '/echo/html/', 
      data: { 
       html: '<p>This is echoed the response in HTML format</p>', 
       delay: 1 
      }, 
      dataType: 'html', 
      beforeSend: function() { 
       console.log('Fired prior to the request') 

      }, 
      success: function(data) { 
       console.log('Fired when the request is successfull'); 
       $('.document').append(data); 
      }, 
      complete: function() { 
       console.log('Fired when the request is complete'); 
      } 
     }) 

     var newDeferred = $.Deferred() 

     var timeoutDeferred = $.Deferred() 

     setTimeout(function(){ 
      console.log('hello world!') 
      timeoutDeferred.resolve() 
     }, 2000) 

     $.when(timeoutDeferred, ajaxDeferred).then(function(){ 
      newDeferred.resolve() 
     } 
     ); 


     return newDeferred; 
    } 

function defferedFunction(e){ 
    $.when(ajaxFunction(e)).done(function(){alert('all done!')}) 
} 
3

Вы можете вернуть обещание

function ajaxFunction(e) { 
     e.preventDefault(); 

     // ajax request 
    return $.ajax({  // return promise 
      async: true, 
      cache: false, 
      type: 'post', 
      url: '/echo/html/', 
+0

Есть хороший способ задержки функции от возвращения обещание до любой другой код в функции не закончил? В этой скрипке, например: http://jsfiddle.net/mq4Sj/6/ – ckersch

+0

Хотелось бы подождать, пока журнал «hello world» не вернет обещание. – ckersch

+0

Нет, оба ajax и setTimeout являются асинхронными, они не блокируют выполнение –

1

Пару вещей. Как @pXL заявил, что вам нужно вернуть обещание. Кроме того, в вашей скрипке вам необходимо передать параметр (d) из вашего дефферируемого функционала в вашу ajaxFunction. Наконец, измените ваш .then на .done (function (a) {});

http://jsfiddle.net/mq4Sj/5/

$(function() { 

    $('.document').on('click', '.ajax', defferedFunction); 

}); 

function defferedFunction(e){ 
     $.when(ajaxFunction(e)).done(function(d){ 
     alert(d); // ->> response from server. 
}) 
    }