Promise的原理
Promise其实内部也有一个defers队列存放事件,.then的事件就在里面,程序开始执行的时候,.then就已经放入下一个事件,然后后面当异步操作完成时,resolve触发事件队列中的事件,便完成了一个.then操作, 其实到这里我们就可以很快地想出一种解决方案,每次异步操作完成通过resolve触发事件并将事件从事件队列中移除,通过事件队列中的事件的resolve使事件的触发持续下去。
我们可以用十几行代码就可以实现这样的逻辑,实现一个简单的异步编程方案
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)
})
控制台得到如下结果:
get...
get 1
get...
get 2
2
Promise.all()
Promise.all() 它接收一个promise对象组成的数组作为参数,并返回一个新的promise对象。
当数组中所有的对象都resolve时,新对象状态变为fulfilled,所有对象的resolve的value依次添加组成一个新的数组,并以新的数组作为新对象resolve的value。
当数组中有一个对象reject时,新对象状态变为rejected,并以当前对象reject的reason作为新对象reject的reason。
简单实现一个:
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() 它同样接收一个promise对象组成的数组作为参数,并返回一个新的promise对象。
与Promise.all()不同,它是在数组中有一个对象(最早改变状态)resolve或reject时,就改变自身的状态,并执行响应的回调。
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)
}
})
}