听别人说是常考知识点,因此备注下。
1.Promise.finally
场景:无论promise执行成功或者失败的,都会走一下finally方法,做一下资源释放的工作。类似try catch finally。
Promise.prototype.finally = function (callback) {
let P = this.constructor;
return this.then(
value => P.resolve(callback()).then(() => value),
reason => P.resolve(callback()).then(() => { throw reason })
);
};
2.Promise.each
场景:每个promise执行完成后,都执行调用一下
Promise.each = (promiseList) => {
let p = new Promise((resolve, reject) => {
for (const item of items) {
item.then((r, j) => {
resolve(r);
});
}
})
return p;
}
3.Promise.first
场景:一个页面当前正处于loading状态,同时请求了多个接口,无论哪个接口正确返回结果,则loading效果取消!或者其他的要获取获取第一个完成状态的值
Promise.first = (promiseList) => {
return new Promise((resolve, reject) => {
let i = 0;
promiseList.forEach(p => {
p.then(resolve).catch(() => {
if (++i === promiseList.length) {
reject('All promises not resolve')
}
});
})
})
}
4.Promise.last
场景:与Promise.first对应的则是Promise.last,获取最后变成完成状态的值。这里与Promise.first不同的是, 只有最后一个Promise都变成最终态(完成或拒绝),才能知道哪个是最后一个完成的,这里我采用了计数的方式,then和catch只能二选一,等计数器达到list.length时,执行外部的resolve。
Promise.last = promiseList => {
return new Promise((resolve, reject) => {
let i = 0;
let lastResult = null;
const fn = () => {
if (++i === promiseList.length) {
lastResult === null ? reject('All promises not resolve') : resolve(lastResult);
}
}
promiseList.forEach(p => {
p.then(res => {
lastResult = res;
fn()
}, () => {
fn()
});
})
})
}
5.Promise.none
场景:Promise.none与Promise.all正好相反,所有的promise都被拒绝了,则Promise.none变成完成状态。 该方法可以用Promise.first来切换,当执行Promise.first的catch时,则执行Promise.none中的resolve。
Promise.none = promiseList => {
return new Promise((resolve, reject) => {
let i = 0;
let results = [];
promiseList.forEach(p => {
p.then(() => {
reject('Some one resolved');
}, (err) => {
results.push(err.message);
if (++i === promiseList.length) {
resolve(results);
}
});
})
})
}
6.Promise.any
场景:Promise.any表示只获取所有的promise中进入完成状态的结果,被拒绝的则忽略掉。
Promise.any = promiseList => {
return new Promise((resolve, reject) => {
let i = 0;
let results = [];
let fn = () => {
if (++i === promiseList.length) {
resolve(results);
}
}
promiseList.forEach(p => {
p.then((res) => {
results.push(res);
fn();
}, (err) => {
fn();
});
})
})
}