为什么我的自定义 Promise.race 实现支持解析的输入?



当我将 Promise 对象传递给它时,下面的自定义实现Promise.race工作正常。但是,如果我传递Promise.reject它会忽略它,只是解析为Promise.resolve值。

function race(promises) {
return new Promise((resolve, reject) => {
function resolveCB(value) {
resolve(value);
}
function rejectCB(value) {
reject(value);
}
promises.forEach((p) => {
p.then(resolveCB).catch(rejectCB);
});
});
}
const p1 = Promise.reject(1)
const p2 = Promise.reject(5)
const p3 = Promise.resolve(2)
race([p1, p2, p3]).then(result => console.log(result)).catch(err => console.log(err));

上面的代码记录2.我希望它能记录1.

const p1 = new Promise((resolve, reject) => {
setTimeout(() => reject(1), 1500);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => resolve(6), 1000);
});
const p3 = new Promise((resolve, reject) => {
setTimeout(() => reject(8), 500);
});

这记录8按预期进行,因此问题不在于功能race似乎不在于,而在于我猜Promise.reject的误解?

如果您在forEach中切换thencatch的顺序,您可以看到预期的结果。then占用微任务队列中的空间,即使 Promise 拒绝和缺少catch处理程序意味着它实际上并没有转换 promise。

promises.forEach((p) => {
// This demonstrates how the results are sensitive to the order, but
// creates the opposite ordering: rejected promises are favored
// over resolved ones.
p.catch(rejectCB).then(resolveCB);
});

function race(promises) {
return new Promise((resolve, reject) => {
function resolveCB(value) {
resolve(value);
}
function rejectCB(value) {
reject(value);
}
promises.forEach((p) => {
p.catch(rejectCB).then(resolveCB);
});
});
}
const p1 = Promise.reject(1)
const p2 = Promise.reject(5)
const p3 = Promise.resolve(2)
race([p1, p2, p3]).then(result => console.log(result)).catch(err => console.log(err));

不过,最好只是使用then的正常双参数行为,以便这两种结果同时发生:

promises.forEach((p) => {
p.then(resolveCB, rejectCB);
});

function race(promises) {
return new Promise((resolve, reject) => {
function resolveCB(value) {
resolve(value);
}
function rejectCB(value) {
reject(value);
}
promises.forEach((p) => {
p.then(resolveCB, rejectCB);
});
});
}
const p1 = Promise.reject(1)
const p2 = Promise.reject(5)
const p3 = Promise.resolve(2)
race([p1, p2, p3]).then(result => console.log(result)).catch(err => console.log(err));

(除了玩具或家庭作业问题之外,您应该使用内置race或通用的 polyfill。FWIW,core-js填充使用双参数then

相关内容

  • 没有找到相关文章

最新更新