在另一个AJAX调用之前重用JavaScript AJAX调用

在另一个AJAX调用之前重用JavaScript AJAX调用,javascript,jquery,ajax,Javascript,Jquery,Ajax,我有两个按钮都执行AJAX调用: $("#save").click(function() { $.ajax({ type: "POST", url: saveEntryURL, data: { id: $("#id").val() }, success: function(r) { ... }, error: function(r) { ...

我有两个按钮都执行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) {
            ...
        }
    })
})
要求是,当用户单击finalize按钮时,系统将首先执行保存,然后再实际将其标记为final。为了重用附加到save按钮的代码,我在实际的AJAX调用之前调用save按钮的
onclick
监听器,如下所示:

$("#tag-as-final").click(function() {
    $("#save").click()
    ^^^^^^^^^^^^^^^^^^    
    $.ajax({
        type: "POST",
        url: finalizeEntryURL,
但它不会执行“保存并完成后”行为,因为两个AJAX调用都是异步的。我需要一个接一个地运行,但是不能让save按钮的AJAX调用同步(在标记发生时,我还做了很多其他事情)。我知道这会很愚蠢,但我在想一些类似于

$("#tag-as-final").click(function() {
    $("#save").click().peformAsyc()
                       ^^^^^^^^^^^^
    $.ajax({
        type: "POST",
        url: finalizeEntryURL,
…这将迫使它在继续之前先完成链式函数的执行,但我知道这是不可用的。有没有办法做到这一点?我目前的工作是在finalize AJAX函数中放置相同的save AJAX函数,尽管它不允许我直接编写代码(不要重复):


这很简单,最好使用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.

我的示例是基本的,只使用了两个级别的嵌套AJAX调用。我可以在三个或更深的嵌套中使用它吗?是的,你可以,尽管我担心我的代码不能真正处理CP。而不是一个更理智的程序流程,可以得到真正的承诺。我将添加一个承诺示例。
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.