1. 定義三個狀態
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
複製程式碼
1. 定義建構函式主題部分
function Promise(executor){
let self = this;
self.status = PENDING;
self.onResolvedCallbacks = [];
self.onRejectedCallbacks = [];
function resolve(value){
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(cb=>cb(self.value));
}
})
}
function reject(reason){
setTimeout(function(){
if(self.status == PENDING){
self.status = REJECTED;
self.value = reason;
self.onRejectedCallbacks.forEach(cb=>cb(self.value));
}
});
}
try{
executor(resolve,reject);
}catch(e){
reject(e);
};
}
複製程式碼
2. 例項擴充套件方法
2.1 then()方法;
Promise.prototype.then = function(onFulfilled,onRejected){
onFulfilled = typeof onFulfilled == 'function'?onFulfilled:function(value){return value};
onRejected = typeof onRejected == 'function'?onRejected:reason=>{throw reason};
let self = this;
let promise2;
if(self.status == FULFILLED){
return promise2 = new Promise(function(resolve,reject){
setTimeout(function(){
try{
let x =onFulfilled(self.value);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
})
});
}
if(self.status == REJECTED){
return promise2 = new Promise(function(resolve,reject){
setTimeout(function(){
try{
let x =onRejected(self.value);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
})
});
}
if(self.status == PENDING){
return promise2 = new Promise(function(resolve,reject){
self.onResolvedCallbacks.push(function(){
try{
let x =onFulfilled(self.value);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
});
self.onRejectedCallbacks.push(function(){
try{
let x =onRejected(self.value);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
});
});
}
}
複製程式碼
2.2 resolvePromise方法;
function resolvePromise(promise2,x,resolve,reject){
if(promise2 === x){
return reject(new TypeError('迴圈引用'));
}
let called = false;
if(x instanceof Promise){
if(x.status == PENDING){
x.then(function(y){
resolvePromise(promise2,y,resolve,reject);
},reject);
}else{
x.then(resolve,reject);
}
}else if(x!= null &&((typeof x=='object')||(typeof x == 'function'))){
try{
let then = x.then;
if(typeof then == 'function'){
then.call(x,function(y){
if(called)return;
called = true;
resolvePromise(promise2,y,resolve,reject)
},function(err){
if(called)return;
called = true;
reject(err);
});
}else{
resolve(x);
}
}catch(e){
if(called)return;
called = true;
reject(e);
}
}else{
resolve(x);
}
}
複製程式碼
2.3 catch()方法;
Promise.prototype.catch = function(onRejected){
this.then(null,onRejected);
}
複製程式碼
2.4 deferred()方法;
Promise.deferred = Promise.defer = function(){
let defer = {};
defer.promise = new Promise(function(resolve,reject){
defer.resolve = resolve;
defer.reject = reject;
});
return defer;
}
複製程式碼
2.5 all()方法;
Promise.all = function(promises){
return new Promise(function(resolve,reject){
let done = gen(promises.length,resolve);
for(let i=0;i<promises.length;i++){
promises[i].then(function(data){
done(i,data);
},reject);
}
});
}
function gen(times,cb){
let result = [],count=0;
return function(i,data){
result[i] = data;
if(++count==times){
cb(result);
}
}
}
複製程式碼
2.6 racel()方法;
Promise.race = function(promises){
return new Promise(function(resolve,reject){
for(let i=0;i<promises.length;i++){
promises[i].then(resolve,reject);
}
});
}
複製程式碼
2.7 resolve()方法;
Promise.resolve = function(value){
return new Promise(function(resolve){
resolve(value);
});
}
複製程式碼
2.8 reject()方法;
Promise.reject = function(reason){
return new Promise(function(resolve,reject){
reject(reason);
});
}
複製程式碼