Promise表示一個非同步操作的最終結果。與Promise最主要的互動方法是通過將函式傳入它的then方法從而獲取得Promise最終的值或Promise最終最拒絕(reject)的原因。
Promise解決的問題是以往在js函式中使用回撥函式的問題。 沒有Promise之前:
function personInfo(callback){
//dosometing
callback&&callback();
}
複製程式碼
原生Promise用法
let p=new Promise((resolve,reject)=>{
resolve('123');
});
p.then(data=>{console.log(data)});
複製程式碼
按照Promise/A+規範來實現一個Promise類。
Promise有三個狀態:pending, fulfilled 或 rejected。
初始化狀態為pending
成功狀態為fulfilled
失敗狀態rejected
self.value存放的是成功的值
self.reason存放的是失敗的值
self.onResolvedCallbacks存的是所有成功回撥的值
self.onRejectedCallbacks存的是所有失敗回撥的值
function Promise(executor){
let self=this;
self.status='pending';
self.value=undefined;
self.reason=undefined;
self.onResolvedCallbacks=[];
self.onRejectedCallbacks=[];
function resolve(value){
//new Promise(new Promise((resolve,reject)=>resolve()));
if(value!=null &&value.then&&typeof value.then == 'function'){
return value.then(resolve,reject);
}
setTimeout(function(){
if(self.status=='pending'){
self.status='fulfilled';
self.value=value;
self.onResolvedCallbacks.forEach(item=>item(self.value));
}
});
}
function reject(reason){
setTimeout(function(){
if(self.status=='pending'){
self.status='rejected';
self.reason=reason;
self.onRejectedCallbacks.forEach(item=>item(self.reason));
}
});
}
try{
executor(resolve,reject);
}catch(e){
reject(e);
}
}
複製程式碼
建構函式原型上的then方法,通過狀態獲取值。返回一個新的Promise例項。
Promise.prototype.then=function(onFulfilled,onRejected){
onFulfilled=typeof onFulfilled=='function'?onFulfilled:value=>value;
onRejected=typeof onRejected=='function'?onRejected:reason=>{throw reason};
let self=this
let promise2;
if(self.status=='resolve'){
return promise2=new Promise((resolve,reject)=>{
try{
let x=onFulfilled(self.value);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e)
}
});
}
if(self.status=='reject'){
return promise2=new Promise((resolve,reject)=>{
try{
let x = onRejected(self.reason);
resolvePromise(promise2, x, resolve, reject);
}catch(e){
reject(e)
}
});
}
if(self.status=='pending'){
return promise2 = new Promise(function (resolve, reject) {
self.onResolvedCallbacks.push(()=>{
try {
let x = onFulfilled(self.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
self.onRejectedCallbacks.push(()=>{
try {
let x = onRejected(self.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
})
}
}
複製程式碼
錯誤捕獲,走失敗的回撥函式
Promise.prototype.catch = function(onRejected){
this.then(null,onRejected);
}
複製程式碼
Promise.all所有的Promise執行完,再執行下一步。接受的引數是個陣列,返回有一個新的Promise例項。陣列中的每一項必須為成功態,then得到的值也會依次按順序排列在陣列中
Promise.all=function(promises){
return new Promise((resolve,reject)=>{
let result=[];
let count=0;
let len=promises.length;
for(let i=0;i<promises.length;i++){
promises[i].then((data)=>{
result[i]=data;
if(++count==len){
resolve(result);
}
},reject);
}
});
}
複製程式碼
Promise.race一個Promise執行完,就執行下一步。接受的引數是個陣列,返回有一個新的Promise例項。
Promise.race = function(promises){
return new Promise(function(resolve,reject){
for(let i=0;i<promises.length;i++){
promises[i].then(resolve,reject);
}
});
}
複製程式碼
Promise.resolve返回一個成功態的Promise例項
Promise.resolve = function(value){
return new Promise(function(resolve,reject){
resolve(value);
});
}
複製程式碼
Promise.reject返回一個失敗態的Promise例項
Promise.reject = function(reason){
return new Promise(function(reresolve,reject){
reject(reason);
});
}
複製程式碼