標籤:one tail values 接下來 method ret and tracking rom
上一篇文章"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();// 返回這個延遲物件的Promisevar 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, 2, 3, 4, 5 );
使用$.when()解決AJAX非同步難題之:多個ajax操作進行邏輯與(and)