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