喜欢做多个依赖的ajax同步调用的方法

des*_*lee 1 javascript ajax jquery asynchronous

我已经看到了做多个依赖ajax同步调用的不同方法.其中两个被广泛采用的是jquery延迟方法和成功回调.

我的问题是:
1)使用一个在另一个上有什么好处?
2)在什么情况下,一个人优先于另一个人?
3)还有比这2更好的方法吗?

// jquery defer method
var defer = $.when(
    $.get('ajax_call_1');
);

defer.done(function () {
    $.get('ajax_call_2');
});



// callback on success
$(function(){ 
    $.ajax({
      url:'/ajax_call_1',
      data: {  },
      success: function(data){      
        $.get('ajax_call_2');
      }
    });
  }
});
Run Code Online (Sandbox Code Playgroud)

jfr*_*d00 6

使用Promise而不是回调的一些原因:

  1. 对多个异步操作进行排序要简单得多.
  2. 构建涉及多个异步操作的条件逻辑要简单得多.
  3. 执行涉及多个异步操作的强大错误处理要简单得多.
  4. 构建可重用的异步接口要简单得多.
  5. 与其他异步接口接口要简单得多.
  6. 更容易处理可能在异步代码中发生的异常,否则会导致静默失败

在您的问题中,对jQuery Ajax调用进行排序并捕获所有可能错误的最简单方法是使用从$.ajax()它返回的自然promise 并将它们链接起来:

$.get('ajax_call_1').then(function(value) {
    return $.get('ajax_call_2');
}).then(function(result) {
    // success with both here
}, function(err) {
    // error with one of them here
});
Run Code Online (Sandbox Code Playgroud)

或者,没有像您的示例中那样的错误处理:

$.get('ajax_call_1').then(function(value) {
    $.get('ajax_call_2');
})
Run Code Online (Sandbox Code Playgroud)

这里没有理由使用这个构造:

// jquery defer method
var defer = $.when(
    $.get('ajax_call_1');
);
Run Code Online (Sandbox Code Playgroud)

因为$.get()已经返回一个承诺所以没有必要使用$.when()只是创建另一个承诺. $.when()当你有多个承诺并想要知道所有这些承诺何时完成时,它非常有用.对于一个承诺,您只需直接使用它 - 没有理由使用$.when()单一承诺.


你可以用第二种方式做到:

// callback on success
    $.ajax({
      url:'/ajax_call_1',
      data: {  },
      success: function(data){      
        $.get('ajax_call_2');
      }
    });
Run Code Online (Sandbox Code Playgroud)

因为这只是使用嵌套回调进行编码的非承诺方式.主要的缺点是,当不使用promises时,错误的传播和多个操作的排序变得混乱和困难.在这个简单的示例中,尝试从任一ajax调用返回到调用者的错误.这需要很多额外的代码.上面的我的承诺示例将所有错误传播回调用者.


至于你的具体问题:

1)使用一个在另一个上的优势是什么?

你基本上问为什么使用promises而不是嵌套的回调.关于使用承诺的优势有数百篇文章.我会看看我是否可以找到一两个,但谷歌搜索"为什么承诺与回调"应该让你开始阅读.

JavaScript Promises有什么好处?

对异步编程保持缄默

我为什么要转向承诺

2)在什么情况下,一个人优先于另一个人?

我知道没有理由为什么普通的嵌套回调比使用promises更受欢迎.一旦你学会了承诺,你几乎总会发现它们是一种更好的编码方式.我不使用promises的唯一原因是,如果我试图创建与没有承诺的旧浏览器兼容的代码,那么我可能只是包含一个polyfill,以便支持promises.

3)还有比这2更好的方法吗?

是的,请参阅我的第一个代码示例.


PS请注意,我选择仅使用.then()jQuery promises,因为这是ES6承诺标准,并且当jQuery将其承诺转换为更符合标准(他们正在处理)时,它将使未来更容易.在与使用该标准的其他承诺来源进行交互时,您的代码也会更加一致.

PPS Promises是一次性设备.他们要么只解决一次,要么拒绝一次.如果您尝试从某些来源获取多个通知,则不会为此构建承诺.事件发射器或发布/订阅系统可能更适合该类型的问题.