/**
* 使用MyPromise模擬Promise基本功能:
* MyPromise新建就立即執行其參數fn,這點比較重要
* fn裏面必須調用狀態函數resolve或者reject之一
* 每次.then接受一個處理MyPromise當前狀態的回調函數,包括resolve和reject(都是異步執行)
* 回調函數裏面默認或者顯式返回一個新的MyPromise,之後的then中的回調是處理新的MyPromise的狀態
* 每次resolve或者reject執行就形成了一個新的MyPromise(並立即執行),後續的then會處理其狀態,這樣就保證默認的狀態不會改變
*
* 使用MyPromise.prototype.events保存時間,其實then鏈是最先執行的
* 每次resolve或者reject都會使得events中的第一個回調出隊列
*
* @param fun
* @constructor
*/
function MyPromise(fun){
//用於生成MyPromise的id,其實在then執行的時候,都是利用同一個MyPromise將回調保存在events
this.id = ++MyPromise.prototype.counts;
var that = this;
var resolve = function(value){
var events = MyPromise.prototype.events;
if(events.length>0){
console.log("call resolve Promise"+that.id);
var func = events.shift().res;//取出events隊列頭中的回調
//異步執行,實際上是生成了新的MyPromise
setTimeout(function(){func(value)},0);
}
};
var reject = function(value){
var events = MyPromise.prototype.events;
if(events.length>0){
console.log("call reject Promise"+that.id);
var func = events.shift().rej;//取出events隊列頭中的回調
//異步執行,實際上是生成了新的MyPromise
setTimeout(function(){func(value)},0);
}
};
//立即執行
fun(resolve,reject);
}
MyPromise.prototype.counts = 0;
MyPromise.prototype.events = [];//回調隊列
/**
* then方法用於保存回調
* @param res
* @param rej
* @returns {MyPromise}
*/
MyPromise.prototype.then = function(res, rej){
var events = MyPromise.prototype.events;
//默認的狀態處理,所以可以不斷的調用.then並生成新的MyPromise
var _res = function(value){return new MyPromise(function(res,rej){res(value)});};
var _rej = function(value){return new MyPromise(function(res,rej){rej(value)});};
if(res){
_res = function(value){
var result = res(value);
if(result instanceof MyPromise)return result;
return new MyPromise(function(res,rej){res(value)});
};
}
if(rej){
_rej = function(value){
var result = rej(value);
if(result instanceof MyPromise)return result;
return new MyPromise(function(res,rej){rej(value)});
};
}
events.push({res:_res,rej:_rej});
console.log("call .then, Events Counts"+events.length);
return this;
};
var getJSON = function(json){
return new MyPromise(function(resolve,reject){
setTimeout(function(){
if(json=="6"){
reject(("error from 3"));
}else{
resolve(json);
}
},1000);
});
};
getJSON("1")
.then(function(json){
console.log(json);
})
.then(function(json){
console.log(json);
})
.then(function(json){
console.log(json);
return getJSON("2");
})
.then(function(json){
console.log(json);
})
.then(null,function(json){//如果不能正確處理狀態,會跳過
console.log(json);
})
.then(function(json){
console.log(json);
return getJSON("6");
})
.then(function(json){
console.log(json);
})
.then(null,function(json){
console.log(json);
})
.then(function(json){
console.log(json);
})
.then(null,function(json){
console.log(json);
});
輸出:
call .then, Events Counts1
call .then, Events Counts2
call .then, Events Counts3
call .then, Events Counts4
call .then, Events Counts5
call .then, Events Counts6
call .then, Events Counts7
call .then, Events Counts8
call .then, Events Counts9
call .then, Events Counts10
call resolve Promise1
1
call resolve Promise2
1
call resolve Promise3
1
call resolve Promise4
2
call resolve Promise5
call resolve Promise6
2
call reject Promise7
call reject Promise8
error from 3
call reject Promise9
call reject Promise10
error from 3