对于promise,手写相关api常用于考察对于promise的理解深度,Promise.all和Promise.race就是其中经常考察的api之一。本文主要使用通俗易懂的语言解说,应如何轻松的实现这两个api。
关于返回值
这两个api都返回一个新的promise,因此我们可以使用new创建一个promise,并返回:
Promise.all = function (promises) {
return new Promise((resolve,reject)=>{});
}
Promise.race = function (promises) {
return new Promise((resolve,reject)=>{});
}
如果传入的不是可迭代对象
这两个都要求传入的参数是可迭代对象,如果不是,则应抛出一个错误:
Promise.all = function (promises) {
if(typeof promises?.[Symbol.iterator] !== 'function') {
throw new Error('TypeError: param is not iterable');
}
return new Promise((resolve,reject)=>{});
}
Promise.race = function (promises) {
if(typeof promises?.[Symbol.iterator] !== 'function') {
throw new Error('TypeError: param is not iterable');
}
return new Promise((resolve,reject)=>{});
}
如果传入的数组为空
这两个api对于数组为空的处理大不相同:
Promise.all: 立即返回一个包含所有兑现值的数组,即空数组。Promise.race: 如果传入的iterable为空,返回的 promise 就会一直保持待定状态。不调用resolve和reject,只调用return即为这种效果。
综上,可为:
Promise.all = function (promises) {
if(typeof param?.[Symbol.iterator] === 'function') {
throw new Error('TypeError: param is not iterable');
}
return new Promise((resolve,reject)=>{
const len = promises.length;
if(len === 0){
resolve([]);
} else {
}
});
}
Promise.race = function (promises) {
if(typeof param?.[Symbol.iterator] === 'function') {
throw new Error('TypeError: param is not iterable');
}
return new Promise((resolve,reject)=>{
const len = promises.length;
if(len === 0) {
return;
} else {
}
});
}
主体逻辑
下面是主体逻辑:
- Promise.all: 等待所有兑现(或第一个拒绝)的结果,并存储在结果数组中返回。
- Promise.race: 随着第一个 promise 的敲定而敲定。
Promise.all = function (promises) {
if(typeof param?.[Symbol.iterator] === 'function') {
throw new Error('TypeError: param is not iterable');
}
return new Promise((resolve,reject)=>{
const len = promises.length;
let result = [];
let index = 0;
if(len === 0){
resolve([]);
} else {
for(let i = 0; i < len; i++ ) {
Promise.resolve(promises[i]).then((data) => {
index++;
result[i] = data;
if(index === len) {
resolve(result);
}
},err => {
reject(err);
})
}
}
});
}
Promise.race = function (promises) {
if(typeof param?.[Symbol.iterator] === 'function') {
throw new Error('TypeError: param is not iterable');
}
return new Promise((resolve,reject)=>{
const len = promises.length;
if(len === 0) {
return;
} else {
for(let i = 0; i < len; i++ ) {
Promise.resolve(promises[i]).then((data) => {
resove(data);
},err => {
reject(err);
})
}
}
});
}
全文完。