在這篇文章中,我們將來說明一下when
與then(pipe)
的用法,這兩個方法都算是promise
衍伸技術。
deferred.when
在實務上很常有這種要求,任務1與任務2這兩個非同步方法執行完成,再執行任務3,這時我們就可以運用when
來完成這種類型的工作。
When
相當與執行Promise
情況的AND
。也就是說一旦給定的所有Promise
均已執行後,就立即執行when
方法產生的Promise
對象。而一旦任一個Promise
被拒絕,則立即拒絕when
產生的Promise
。
下列程式碼為when
的基本使用方法。
var promise1 = $.get('/test1');
var promise2 = $.get('/test2');
$.when(promise1,promise2).done(function(){
//promise1與promise2都完成時會執行的事情。
});
如果要取得promise1
與promise2
的回傳參數則如下程式碼,其中arg1
為promise1
的回傳參數,而arg2
為promise2
的回傳參數。
var promise1 = $.get('/test1');
var promise2 = $.get('/test2');
$.when(promise1,promise2).done(function(arg1,arg2){
//promise1與promise2都完成時會執行的事情。
});
##d eferred.then(.pipe)
從Jquery1.8
開始,官網建議將deferred.pipe()
由deferred.then()
替代。
deferred.then()
方法的回傳可以做以下兩件事。
- 如果
then
回傳為promise
物件,則then
生成的promise
物件會模仿這個promise
物件。 - 如果
then
回傳為非promise
物件,則then
生成的promise
物件會立即因該回傳值而執行、拒絕或通知,取決於then
那個初使promise
發生什麼事了。
來看看使用情況,假設某api
回傳發生錯誤時,不是回傳http status XXX
,而是回傳個Json
如{error:true}
之類的,由於promise
是在http
請求失敗時,才會觸發,因為我們會將處理錯誤流程寫在done
裡。
$.get('/getData')
.done(function(response) {
if(response.error) {
console.log('Error');
}else {
console.log('Success');
}
})
.fail(function(response) {
console.log('Error');
});
上述程式碼,不是個好的解決方法,非得要在done
做兩次判斷,因此我們這時就可以使用.then
,來過濾Promise
,如下程式碼。
var getData = $.get('/getData').then(function(response){
if(response.error)
return $.Deferred().reject(response);
else
return response;
},function(response){
return $.Deferred().reject(response);
});
getData.done(function(response){
console.log("Success");
}).fail(function(){
console.log("Fail");
});
這樣在done
就不需要在進行兩次判斷,其中then
的回傳值為promise
,因此該promise
會模仿$.get('/getData')
的promise
。