2015-08-03 3 views
1

У меня есть две кнопки, и выполняет AJAX вызов:Повторное использование вызова JavaScript AJAX, прежде чем другой вызов AJAX

$("#save").click(function() { 
    $.ajax({ 
     type: "POST", 
     url: saveEntryURL, 
     data: { id: $("#id").val() }, 
     success: function(r) { 
      ... 
     }, 
     error: function(r) { 
      ... 
     } 
    }) 
}) 

$("#tag-as-final").click(function() { 
    $.ajax({ 
     type: "POST", 
     url: finalizeEntryURL, 
     data: { id: $("#id").val() }, 
     success: function(r) { 
      ... 
     }, 
     error: function(r) { 
      ... 
     } 
    }) 
}) 

Требование в том, что, когда пользователь нажимает кнопку ФИНАЛИЗ, система сначала выполнить сохранить до фактического пометив его как окончательный. Чтобы повторно использовать код, прикрепленный к кнопке сохранения, я называю onclick слушателю кнопку сохранения до фактического AJAX вызова, как это:

$("#tag-as-final").click(function() { 
    $("#save").click() 
    ^^^^^^^^^^^^^^^^^^  
    $.ajax({ 
     type: "POST", 
     url: finalizeEntryURL, 

Но это не будет делать «копи-и финализации-после» поведения, так как оба вызова AJAX являются асинхронными. Мне нужно запускать один за другим, но не могу позволить сделать вызов AJAX кнопки сохранения синхронным (у меня также много других вещей, в то время как происходит тегирование). Я знаю, что это было бы глупо, но я думаю, что-то подобное ...

$("#tag-as-final").click(function() { 
    $("#save").click().peformAsyc() 
         ^^^^^^^^^^^^ 
    $.ajax({ 
     type: "POST", 
     url: finalizeEntryURL, 

... что заставит его закончить выполнение первого цепную функции, прежде чем продолжить, но я знаю, что нет в наличии. Есть какой-либо способ сделать это? Моя текущая работа вокруг ставит ту же функцию сохранения AJAX внутри функции финализации AJAX, хотя она не позволяет мне код DRY (не повторяться):

$("#tag-as-final").click(function() { 
    $.ajax({ 
     type: "POST", 
     url: saveEntryURL, 
     data: { id: $("#id").val() }, 
     success: function(r) { 
      ... 
      $.ajax({ 
       type: "POST", 
       url: finalizeEntryURL, 
       data: { id: $("#id").val() }, 
       success: function(r) { 
        ... 
       }, 
       error: function(r) { 
        ... 
       } 
      }) 
     }, 
     error: function(r) { 
      ... 
     } 
    }) 
}) 

ответ

2

Это довольно просто, вам лучше используя jquery «обещания». Как так:

var generalSettings = { }; //Settings for AJAX call. 
var jqXHR = $.ajax(generalSettings); //Do AJAX call. 
generalSettings.data = 'newdata'; //update generalSettings 
jqXHR.done(function(data){ 
    $.ajax(generalSettings); //New Petition with updated settings. 
}); 

Это использует ES6 обещания и JQuery обещает:

function doAjaxAsPromise(settings){ 
    return new Promise(function(resolve){ 
     var jqXHR = $.ajax(settings); 
     jqXHR.done(function(data){ 
      resolve(data); 
     }); 
    }); 
} 

var settings = { }; 
var petition = doAjaxAsPromise(settings); 
var secondpetition = petition.then(function(data){ 
    //work with data 
    //new settings 
    var settings = { }; 
    return doAjaxAsPromise(settings); 
}); 
var thirdpetition = secondpetition.then(function(data){ 
    //work with data 
    //new settings 
    var settings = { }; 
    return doAjaxAsPromise(settings); 
}); 
//If needed to reuse settings object outside promise scope: 
//var settings = Object.create(settings); 

Некоторые другие хорошо, что вы можете сделать для повторного использования кода:

function save(settings) { 
    var prom = doAjaxAsPromise(settings); 
    return prom.then(function(data){ 
     //do something with your data. 
    }); 
} 

function tagAsFinal(savedPromise, settings){ 
    return savedPromised.then(function(){ 
     var prom = doAjaxAsPromise(settings); 
     return prom.then(function(data){ 
      //work with data; 
     }); 
    }); 
} 

$('save').on('click', function(){ 
    save(settings); //settings = $.ajax settings. 
}); 

$('tagAsFinal').on('click', function(){ 
    var generalSettings = { }; 
    var settingsone = Object.create(generalSettings); 
    var settingstwo = Object.create(generalSettings); 
    var saved = save(settingsone); //$.ajax settings. 
    tagAsFinal(saved, settingstwo); 
}); 
//Can still be reduced. 
+0

Мой пример является основным, используя только два уровня вложенного вызова AJAX. Могу ли я использовать это на трех или более глубоких гнездованиях? – Gideon

+0

Да, вы можете, хотя я боюсь, что мой код на самом деле не справляется с CPS. Вместо более разумного потока программ, который получал бы с настоящими обещаниями. Я добавлю пример с обещанием. – MinusFour

Смежные вопросы