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

时间:2015-08-03 01:17:54

标签: javascript jquery 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) {
            ...
        }
    })
})

要求是当用户单击“完成”按钮时,系统将首先执行保存,然后将其标记为最终。要重用附加到保存按钮的代码,我会在实际的AJAX调用之前调用保存按钮的onclick侦听器,如下所示:

$("#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) {
            ...
        }
    })
})

1 个答案:

答案 0 :(得分:2)

非常简单,你最好使用jquery" promises"。像这样:

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.