1. 实现Promise.all
promise.all(iterable)
返回一个新的promise
实例。此实例在iterable
参数内所有的promise
都fulfilled
或者参数中不包含promise
时,状态才变成fulfilled
;如果参数中有一个失败rejected
,此实例回调失败,失败的信息是第一个失败promise
的返回结果。let p1 = new Promise(function (resolve, reject) {
resolve(42);
})
let p2 = new Promise(function (resolve, reject) {
resolve(43);
})
let p3 = new Promise(function (resolve, reject) {
resolve(44);
})
let p4 = Promise.all([p1, p2, p3]);
p4.then(function (value) {
console.log(value); // [ 42, 43, 44 ]
})
let p1 = new Promise(function (resolve, reject) {
resolve(42);
})
let p2 = new Promise(function (resolve, reject) {
reject(43);
})
let p3 = new Promise(function (resolve, reject) {
resolve(44);
})
let p4 = Promise.all([p1, p2, p3]);
p4.catch(function (value) {
console.log(value); // 43
})
所以总结promise.all
的特点,即为:
如果传入的参数为空的可迭代对象,promise.all
会同步地返回一个已完成状态的promise
;如果传入的参数中不包含任何promise
,promise.all
会异步地返回一个已完成状态的promise
;其他情况下,promise.all
返回一个处理中(pending
)状态的promise
。
promise.all
的返回值是一个promise
实例,如果传入的参数中的promise
都变成完成状态,promise.all
返回的promise
异步地变成完成;如果传入的参数中有一个promise
失败,promise.all
将异步地见失败的结果给失败状态回调函数,而不管其他promise
是否完成;并且在任何情况下,promise.all
返回的promise
的完成状态的结果都是一个数组。
promise.all
代码实现Promise.all_ = function(promises) {
return new Promise((resolve, reject) => {
// Array.from()可将可迭代对象转化为数组
promises = Array.from(promises);
if(promises.length===0) {
resolve([]);
} else {
let result = [];
let index = 0;
for(let i=0; i {
result[i] = data;
if(++index===promises.length) {
// 所有的promise状态都是fulfilled,promise.all返回的实例才变成fulfilled状态
resolve(result);
}
}, err => {
reject(err);
return;
})
}
}
})
}
2. 实现Promise.race
Promise.race
返回的仍然是一个Promise
,它的状态与第一个完成的Promise
的状态相同;如果传入的参数是不可迭代的,那么将会抛出错误。let p1 = Promise.resolve(42);
let p2 = new Promise(function (resolve, reject) {
reject(43);
})
let p3 = new Promise(function (resolve, reject) {
resolve(44);
})
let p4 = Promise.race([p1, p2, p3]);
p4.then(function (value) {
console.log(value); // 42
})
Promise.race()
实现Promise.ra_ce = function(promises) {
promises = Array.from(promises);
return new Promise((resolve, reject) => {
if(promises.length===0) {
return;
} else {
for(let i=0; i {
resolve(data);
return;
}, err => {
reject(err);
return;
})
}
}
})
}
3. 可迭代数据结构
Promsie.all
和Promise.race
都只接受可迭代的数据结构,否则会报错,所以在不确定传入的promises
是否为可迭代数据结构的情况下可以通过以下加以判断:
if(typeof promises[Symbol.iterator] !== 'function') {
Promise.reject("args is not iteratable!");
}
ES6
规定,默认的 Iterator
接口部署在数据结构的 Symbol.iterator
属性,换个角度,也可以认为,一个数据结构只要具有 Symbol.iterator
属性(Symbol.iterator
方法对应的是遍历器生成函数,返回的是一个遍历器对象),那么就可以其认为是可迭代的。
Symbol.iterator
属性,Symbol.iterator()
返回的是一个遍历器对象for ... of
进行循环Array.from
转换为数组3. 实现Promise.finally
不管成功还是失败,都会走到finally
中,并且finally
之后,还可以继续then
。并且会将值原封不动的传递给后面的then
。
Promise.prototype.finally = function (callback) {
return this.then((value) => {
return Promise.resolve(callback()).then(() => {
return value;
});
}, (err) => {
return Promise.resolve(callback()).then(() => {
throw err;
});
});
}