使用$.when()解决AJAX异步难题之:多个ajax操作进行逻辑与(and)

上一篇文章"JQuery.deferred提供的promise解决方案",提到了javascript异步操作的3个问题,以及javascript Promise入门。现在我们看下如何利用$.when()来解决上一篇博客中的第3个问题。

考虑这种场景,假如我们同时发送两个Ajax请求,然后要在两个请求都成功返回后再做一件接下来的事,想一想如果只按前面的方式在各自的调用位置去附加回调,这是不是很困难?

使用when(),我们可以通过类似下面的代码解决这个问题。下面这段代码可以实现这个效果:当ajax1和ajax2操作都成功的时候,会调用onDone回调函数

var promise1 = $.ajax(url1),promise2 = $.ajax(url2),promiseCombined = $.when(promise1,promise2);
promiseCombined.done(onDone);

$.when()方法可以合并多个Promise得到一个新的Promise,相当于在原多个Promise之间建立了AND(逻辑与)的关系,如果所有组成Promise都已成功,则令合并后的Promise也成功,如果有任意一个组成Promise失败,则立即令合并后的Promise失败。


1.$.when()不传参数,或者参数既不是Deferred对象也不是Promise对象。这种场景没有什么实际作用。

If a single argument is passed to jQuery.when() and it is not a Deferred or a Promise,it will be treated as a resolved Deferred and any doneCallbacks attached will be executed immediately. The doneCallbacks are passed the original argument. In this case any failCallbacks you might set are never called since the Deferred is never rejected. For example:

$.when( { testing: 123 } ).done(function( x ) {
  alert( x.testing ); // Alerts "123" immediately
});

If you don't pass it any arguments at all,jQuery.when() will return a resolved promise.
$.when().done(function( x ) {
  alert( "I fired immediately" );//x is undefined
});

2.$.when()只有1个参数,该参数是Deferred或者Promise对象。

If a single Deferred is passed to jQuery.when(),its Promise object (a subset of the Deferred methods) is returned by the method. Additional methods of the Promise object can be called to attach callbacks,such as deferred.done. When the Deferred is resolved or rejected,usually by the code that created the Deferred originally,the appropriate callbacks will be called. For example,the jqXHR object returned by jQuery.ajax() is a Promise-compatible object and can be used this way:

$.when( $.ajax( "test.aspx" ) ).done(function( data,textStatus,jqXHR ) {
  alert( jqXHR.status ); // Alerts 200
});

// 创建1个延迟对象
var dtd = $.Deferred();

// 返回这个延迟对象的Promise
var its_promise = $.when(dtd);

// 可以利用promise绑定各种回调函数
its_promise.done(function(){alert("success");});

// 改变状态只能通过Deferred对象
dtd.resolve();

3.$.when()参数是多个Deferred或者Promise对象。这种场景才是when()真正的价值所在。

In the case where multiple Deferred objects are passed to jQuery.when(),the method returns the Promise from a new "master" Deferred object that tracks the aggregate state of all the Deferreds it has been passed. The method will resolve its master Deferred as soon as all the Deferreds resolve,or reject the master Deferred as soon as one of the Deferreds is rejected. If the master Deferred is resolved,the doneCallbacks for the master Deferred are executed. The arguments passed to the doneCallbacks provide the resolved values for each of the Deferreds,and matches the order the Deferreds were passed to jQuery.when(). For example:

var d1 = $.Deferred();
var d2 = $.Deferred();
 
$.when( d1,d2 ).done(function ( v1,v2 ) {
    console.log( v1 ); // "Fish"
    console.log( v2 ); // "Pizza"
});
 
d1.resolve( "Fish" );
d2.resolve( "Pizza" );
这就是相当于2个Promise进行逻辑与操作,得到1个新的Promise。

In the event a Deferred was resolved with no value,the corresponding doneCallback argument will be undefined. If a Deferred resolved to a single value,the corresponding argument will hold that value. In the case where a Deferred resolved to multiple values,the corresponding argument will be an array of those values. For example:

var d1 = $.Deferred();
var d2 = $.Deferred();
var d3 = $.Deferred();
 
$.when( d1,d2,d3 ).done(function ( v1,v2,v3 ) {
    console.log( v1 ); // v1 is undefined
    console.log( v2 ); // v2 is "abc"
    console.log( v3 ); // v3 is an array [ 1,2,3,4,5 ]
});
 
d1.resolve();
d2.resolve( "abc" );
d3.resolve( 1,5 );

相关文章

JS原生Ajax操作(XMLHttpRequest) GET请求 POST请求 兼容性问题 利用iframe模拟ajax 实现表单提交的返回...
AJAX 每日更新前端基础,如果觉得不错,点个star吧 😃 https://github.com/WindrunnerMax/E...
踩坑Axios提交form表单几种格式 前后端分离的开发前后端, 前端使用的vue,后端的安全模块使用的SpringSe...
很早就听闻ajax的名声,但是却一直不知道怎么用,今天自己捣鼓了一下,竟然会用了,哈哈哈哈。 为了防止...
需要在服务器上进行哈 jquery的ajax方法: // jquery请求 $.ajax({ url: "./server/slider.js...
Ajax函数封装ajax.js // Get / Post // 参数 get post // 是否异步 // 如何处理响应数据 // URL // var...