Promise的原理
Promise其實(shí)內(nèi)部也有一個(gè)defers隊(duì)列存放事件痊夭,.then的事件就在里面,程序開始執(zhí)行的時(shí)候,.then就已經(jīng)放入下一個(gè)事件,然后后面當(dāng)異步操作完成時(shí)宾茂,resolve觸發(fā)事件隊(duì)列中的事件瓷马,便完成了一個(gè).then操作, 其實(shí)到這里我們就可以很快地想出一種解決方案跨晴,每次異步操作完成通過(guò)resolve觸發(fā)事件并將事件從事件隊(duì)列中移除欧聘,通過(guò)事件隊(duì)列中的事件的resolve使事件的觸發(fā)持續(xù)下去。
我們可以用十幾行代碼就可以實(shí)現(xiàn)這樣的邏輯端盆,實(shí)現(xiàn)一個(gè)簡(jiǎn)單的異步編程方案
function P(fn) {
var value = null;
var events = [];
this.then = function(f) {
events.push(f);
return this;
}
function resolve(newValue) {
var f = events.shift();
f(newValue, resolve);
}
fn(resolve);
}
function a() {
return new P(function(resolve) {
console.log("get...");
setTimeout(function() {
console.log("get 1");
resolve(1);
}, 1000)
});
}
a().then(function(value, resolve) {
console.log("get...");
setTimeout(function() {
console.log("get 2");
resolve(2);
}, 1000)
}).then(function(value, resolve) {
console.log(value)
})
控制臺(tái)得到如下結(jié)果:
get...
get 1
get...
get 2
2
Promise.all()
Promise.all() 它接收一個(gè)promise對(duì)象組成的數(shù)組作為參數(shù)怀骤,并返回一個(gè)新的promise對(duì)象。
當(dāng)數(shù)組中所有的對(duì)象都resolve時(shí)焕妙,新對(duì)象狀態(tài)變?yōu)閒ulfilled蒋伦,所有對(duì)象的resolve的value依次添加組成一個(gè)新的數(shù)組,并以新的數(shù)組作為新對(duì)象resolve的value焚鹊。
當(dāng)數(shù)組中有一個(gè)對(duì)象reject時(shí)痕届,新對(duì)象狀態(tài)變?yōu)閞ejected,并以當(dāng)前對(duì)象reject的reason作為新對(duì)象reject的reason末患。
簡(jiǎn)單實(shí)現(xiàn)一個(gè):
Promise.all = function(promises){
if(!Array.isArray(promises)){
throw new TypeError('You must pass array')
}
return new Promise(function(resolve,reject){
var result = [],
count = promises.length;
function resolver(value){
resolveAll(value)
}
function rejecter(reason){
reject(reason)
}
function resolveAll(value){
result.push(value)
if(--count ==0){
resolve(result)
}
}
for(var i=0;i<promises.length;i++){
promises[i].then(resolver,rejecter)
}
})
}
Promise.race()
Promise.race() 它同樣接收一個(gè)promise對(duì)象組成的數(shù)組作為參數(shù)研叫,并返回一個(gè)新的promise對(duì)象。
與Promise.all()不同璧针,它是在數(shù)組中有一個(gè)對(duì)象(最早改變狀態(tài))resolve或reject時(shí)嚷炉,就改變自身的狀態(tài),并執(zhí)行響應(yīng)的回調(diào)探橱。
Promise.race = function(promises){
if(!Array.isArray(promises)){
throw new TypeError('You must pass array')
}
return new Promise(function(resolve,reject){
function resolver(value){
resolve(value)
}
function rejecter(reason){
reject(reason)
}
for(var i=0;i<promises.length;i++){
promises[i].then(resolver,rejecter)
}
})
}