1. 程式人生 > >對Promise的一些理解

對Promise的一些理解

摘取部分指令碼之家的描述

Promise核心說明

儘管Promise已經有自己的規範,但目前的各類Promise庫,在Promise的實現細節上是有差異的,部分API甚至在意義上完全不同。但Promise的核心內容,是相通的,它就是then方法。在相關術語中,promise指的就是一個有then方法,且該方法能觸發特定行為的物件或函式。

Promise可以有不同的實現方式,因此Promise核心說明並不會討論任何具體的實現程式碼。

先閱讀Promise核心說明的意思是:看,這就是需要寫出來的結果,請參照這個結果想一想怎麼用程式碼寫出來吧。
起步:用這一種方式理解Promise

回想一下Promise解決的是什麼問題?回撥。例如,函式doMission1()代表第一件事情,現在,我們想要在這件事情完成後,再做下一件事情doMission2(),應該怎麼做呢?

先看看我們常見的回撥模式。doMission1()說:“你要這麼做的話,就把doMission2()交給我,我在結束後幫你呼叫。”所以會是:

	
doMission1(doMission2);

Promise模式又是如何呢?你對doMission1()說:“不行,控制權要在我這裡。你應該改變一下,你先返回一個特別的東西給我,然後我來用這個東西安排下一件事。”這個特別的東西就是Promise,這會變成這樣:?

doMission1().then(doMission2);

可以看出,Promise將回調模式的主從關係調換了一個位置(翻身做主人!),多個事件的流程關係,就可以這樣集中到主幹道上(而不是分散在各個事件函式之內)。

好了,如何做這樣一個轉換呢?從最簡單的情況來吧,假定doMission1()的程式碼是:

function doMission1(callback){
  varvalue = 1;
  callback(value);
}

那麼,它可以改變一下,變成這樣:

function doMission1(){
  return{
    then:function(callback){
      varvalue = 1;
      callback(value);
    }
  };
}

這就完成了轉換。雖然並不是實際有用的轉換,但到這裡,其實已經觸及了Promise最為重要的實現要點,即Promise將返回值轉換為帶then方法的物件。

Promises是什麼

Promises象徵著一個非同步操作的最終結果。Promises互動主要通過它的then方法,then方法接受一個回撥函式,這個回撥函式接受執行成功的返回值或執行失敗的錯誤原因,錯誤原因一般是Error物件。需要注意的是,then方法執行的返回值是一個Promise物件,而then方法接受的回撥函式的返回值則可以是任意的JavaScript物件,包括Promises。基於這種機制,Promise物件的鏈式呼叫就起作用了。

Promises的狀態

Promise物件有三種狀態:pending(初始狀態)、fulfilled(成功執行)、rejected(執行出錯)。pending狀態的Promise物件可以轉換到其它兩種狀態。

而Promise的真正威力在於複雜的多層呼叫

promise鏈式呼叫

var p1 = new Promise(function() {});
var p2 = new Promise(function() {});
var p3 = new Promise(function() {});
// var p4...

p1.then(function(p1_data) {
  return p2;
}).then(function(p2_data){
  return p3;
}).then(function(p3_data){
  return p4;
}).then(function(p4_data){
  //final result
}).catch(function(error){
    //同一處理錯誤資訊
});

這才是promise真正強大的地方,理解了鏈式呼叫,一切就變得簡單了

自己寫了個簡陋的demo:

注:如有需要請自行引用jQuery。以及Ajax 的url更換成有效地址

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    </head>
   
    <body>
	
       <script src="jquery-1.11.2.js"></script>
		<script>

		function getUserInfo(resolve, reject,uid){
			var _url = 'http://XXX';
			$.ajax({
				type: "post",
				url: _url + "get_user_info.php",
				data:{
					user_id:uid
				},
				dataType: "jsonp",
				success: function (data) {
					resolve(data);
				}
			})
		}
		
		function test(uid) {
			var pro = new Promise(function(resolve, reject){
				getUserInfo(resolve, reject,uid);
			})
			return pro;
		}
		
		test(1000016).then(function(data){
			console.error("user 1 is "+JSON.stringify(data));
			return test(1000013);
		}).then(function(data){
			console.error("user 2 is "+JSON.stringify(data));
		})
		
        </script>
    </body>
</html>