about 3 years ago

在這篇文章中,我們將來說明一下whenthen(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都完成時會執行的事情。
});

如果要取得promise1promise2的回傳參數則如下程式碼,其中arg1promise1的回傳參數,而arg2promise2的回傳參數。

var promise1 = $.get('/test1');
var promise2 = $.get('/test2');

$.when(promise1,promise2).done(function(arg1,arg2){
    //promise1與promise2都完成時會執行的事情。
});

deferred.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


參考資料

← Javascript非同步編程的方法(Promise) HTML5之走在平行時空的Web Worker →
 
comments powered by Disqus