Closed azl397985856 closed 4 years ago
just implement it by my intuition, no parameter validation or anything
Promise.any = promises => {
return new Promise((resolve, reject) => {
let hasOneResolved = false
let remaining = promises.length
const errors = []
for (let index in promises) {
promises[index].then(data => {
if (hasOneResolved) return
hasOneResolved = true
resolve(data)
}, err => {
if (hasOneResolved) return
remaining--
errors[index] = err
remaining || reject(errors)
})
}
})
}
/**
* 如果传入的参数是一个空的可迭代对象,则返回一个 已完成(already resolved) 状态的 Promise。
* 如果传入的参数不包含任何 promise,则返回一个 异步完成 (asynchronously resolved)的 Promise。
* @param promises
*/
function any<T>(
promises: (T | PromiseLike<T>)[] | Iterable<T | PromiseLike<T>>
): Promise<T | void> {
let promiseSize: number = 0;
let selfResolve: (value: T) => void;
let selfReject: (reason: unknown) => void;
let rejectedReasons: Array<unknown> = [];
let anyPromise: Promise<T> = new Promise((resolve, reject) => {
selfResolve = (value: T) => {
resolve(value);
};
selfReject = (reason: unknown) => {
if (rejectedReasons.length === promiseSize) {
reject(rejectedReasons);
} else {
rejectedReasons.push(reason);
}
};
});
for (let p of promises) {
if (thenable(p)) {
promiseSize += 1;
p.then(selfResolve, selfReject);
}
}
if (promiseSize === 0) {
return Promise.resolve();
}
return anyPromise;
}
function thenable(p: any): p is Promise<unknown> {
return typeof p.then === 'function';
}
随便写的,仅供参考。
Promise.any = ps => new Promise((resolve, reject) => {
let cnt = 0;
ps.map(p => p.then(resolve).catch((err) => ++cnt === ps.length && reject(err)))
})
测试:
const resolveTimer = ms => new Promise(r => setTimeout(() => r(`${ms}$ elapsed`), ms))
const rejectTimer = ms => new Promise((_, r) => setTimeout(() => r(`${ms}$elapse`), ms))
any([timer(1000), timer(2000), timer(3000)]).then(console.log)
any([rejectTimer(1000), timer(2000), timer(3000)]).then(console.log)
any([rejectTimer(1000), rejectTimer(2000), rejectTimer(3000)]).then(console.log).catch(console.log)
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Promise.any()
是ES2020的一个标准,目前是stage3阶段,它是一个Promise的一个静态方法,这个方法会在其实例列表中至少有一个resolve的时候触发。eg:
请实现之。
PS:
corejs已经实现了,大家也可以参考一下。