1.Promise理解
- Promise本質(zhì)是一個狀態(tài)機港令,每個Promise只能是三種狀態(tài)中的一種:pending,fulfilled窄陡,rejected
狀態(tài)轉(zhuǎn)變只能是 pending -> fulfilled 或者 pending -> rejected炕淮,狀態(tài)轉(zhuǎn)變不可逆
- then方法可以被同一個Promise鏈式調(diào)用多次
- then方法必須返回一個新的Promise
2.Promise實現(xiàn)代碼
function Promise(fn){
//安全的構造函數(shù)
if(!(this instanceof Promise)){
return new Promise(fn);
}
var self=this;
//先執(zhí)行函數(shù)本身,然后調(diào)用resolve的時候運行存儲在doneList中的回調(diào)函數(shù)
this.doneList=[]; //成功回調(diào)函數(shù)隊列
this.failList=[]; //失敗回調(diào)函數(shù)隊列
this.status='PENDING'; //狀態(tài)
this.value=null;
this.error=null;
//Promise改變狀態(tài),執(zhí)行其成功回調(diào)函數(shù)隊列
function resolve(value){
setTimeout(function(){
self.status='FULFILLED';
self.value=value;
self.doneList.forEach(function(done){
self.value=done(self.value); //將計算結果依次傳遞下去
});
});
}
//Promise改變狀態(tài)跳夭,執(zhí)行其失敗回調(diào)函數(shù)隊列
function reject(error){
setTimeout(function(){
self.status='REJECTED';
self.error=error;
self.failList.forEach(function(fail){
self.error=fail(self.error); //將錯誤處理結果依次傳遞下去
});
});
}
fn(resolve,reject);
}
Promise.prototype={
constructor: Promise,
then: function(done,fail){
var self=this;
return new Promise(function(resolve,reject){
//對then中的回調(diào)函數(shù)進行包裝涂圆,并執(zhí)行resolve
function handle(value){
//成功和錯誤處理函數(shù)必須是函數(shù)才調(diào)用,否則直接返回上一個值
var res=typeof done==='function' && done(value) || value;
//如果返回一個Promise對象币叹,則調(diào)用其then方法润歉,等待獲取其中的返回值
if(res && typeof res['then']==='function'){
res.then(function(value){
//調(diào)用resolve時,會執(zhí)行其成功回調(diào)函數(shù)列表
resolve(value);
});
} else {
resolve(res);
}
}
function errback(error){
error=typeof fail==='function' && fail(error) || error;
reject(error);
}
if(self.status==='PENDING'){
self.doneList.push(handle);
self.failList.push(errback);
} else if(self.status==='FULFILLED'){
//已完成后調(diào)用then則直接傳入計算結果
handle(self.value);
} else if(self.status==='REJECTED'){
//已完成后調(diào)用則直接傳入異常
errback(self.error);
}
});
},
resolve: function(arg){
return new Promise(function(resolve,reject){
resolve(arg);
});
},
reject: function(arg){
return new Promise(function(resolve,reject){
reject(arg);
});
},
catch: function(fail){
return this.then(undefined,fail);
}
}
//用Promise.then封裝串行異步函數(shù)
var res=new Promise(function(resolve){
console.log(1);
resolve(2);
}).then(function(num){
return new Promise(function(resolve,reject){
setTimeout(function(){
console.log(num);
resolve(num);
},1000);
});
}).then(function(num){
return new Promise(function(resolve,reject){
setTimeout(function(){
console.log(num);
resolve(num);
},1000);
});
});
//狀態(tài)已改變颈抚,則直接傳入結果或錯誤
res.then(function(num){
console.log(num);
});
console.log(3);
最后編輯于 :
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者