Jquery 的 Promise 之 when 與 then ( pipe )
javascript
Lastmod: 2019-12-13

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

##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

參考資料

comments powered by Disqus