gpt4 book ai didi

javascript - 异步生成器 : Yielding a rejected promise

转载 作者:行者123 更新时间:2023-12-01 16:04:14 26 4
gpt4 key购买 nike

我一直在玩异步生成器,试图制作一个“ promise 排序”生成器,它接受一系列 promise ,并按照它们解决或拒绝的顺序一个接一个地产生 promise 。所以像:

async function* orderProms(prom_arr) {

// Make a copy so the splices don't mess it up.
const proms = [...prom_arr];

while (proms.length) {
// Tag each promise with it's index, so that we can remove it for the next loop.
const {prom, index} = await Promise.race(proms.map((prom, index) => prom.then(
() => ({prom, index}),
() => ({prom, index})
)));

proms.splice(index, 1);
yield prom;
}
}

像这样使用这个生成器的想法:

const resAfter = (val, delay) => new Promise(res => setTimeout(() => res(val), delay));
const rejAfter = (val, delay) => new Promise((_, rej) => setTimeout(() => rej(val), delay));

const promises = [
resAfter("Third", 3000),
resAfter("First", 1000),
rejAfter("Second", 2000), // NOTE: this one rejects!
];

(async () => {

let ordered = orderProms(promises);

let done = false;
for (let next_promise = ordered.next(); !done; next_promise = ordered.next()) {
const next = await next_promise
.catch(err => ({done: false, value: `Caught error: ${err}`}));

done = next.done;
if (!done) console.log(next.value);
}
})()

但是,我注意到这将达到第二个 promise ,然后生成器将停止。似乎是因为拒绝了“第二个” promise 。调用 yield promprom被拒绝。

但这是我困惑的根源。我不想在这里创建异常,我只想将被拒绝的 promise 作为 value迭代器的结果。我不希望它被打开。这几乎就像被视为 yield await prom; ,但如您所见,没有 await称呼。

这里发生了什么,我怎样才能简单地从这个生成器中产生一个被拒绝的 promise 。

这是可运行片段中的上述代码:

async function* orderProms(prom_arr) {

// Make a copy so the splices don't mess it up.
const proms = [...prom_arr];

while (proms.length) {
// Tag each promise with it's index, so that we can remove it for the next loop.
const {prom, index} = await Promise.race(proms.map((prom, index) => prom.then(
() => ({prom, index}),
() => ({prom, index})
)));

proms.splice(index, 1);
yield prom;
}
}

const resAfter = (val, delay) => new Promise(res => setTimeout(() => res(val), delay));
const rejAfter = (val, delay) => new Promise((_, rej) => setTimeout(() => rej(val), delay));

const promises = [
resAfter("Third", 3000),
resAfter("First", 1000),
rejAfter("Second", 2000), // NOTE: this one rejects!
];

(async () => {

let ordered = orderProms(promises);

let done = false;
for (let next_promise = ordered.next(); !done; next_promise = ordered.next()) {
const next = await next_promise
.catch(err => ({done: false, value: `Caught error: ${err}`}));

done = next.done;
if (!done) console.log(next.value);
}
})()

最佳答案

It's almost like this is being treated as yield await prom. What is going on here?



Exactly that是异步生成器的行为方式。

how can I simply yield a rejected promise as-is from this generator.



你不能。请注意,异步迭代器预计将被
try {
for await (const value of orderProms(promises)) {
console.log(value);
}
} catch(err) {
console.error('Caught error: ', err);
}

语法中没有对单个错误处理的便利。当出现异常时,循环停止,生成器完成。观点。

所以,你可以做什么?我看到三个选择:
  • 保持原样并尽早将失败视为一项功能(类似于 Promise.all )
  • 处理错误(在 orderProms 中或在向其中传递 promise 之前)并产生 promise 状态和值的元组
    for await (const value of orderProms(promises.map(prom =>
    prom.catch(err => `Caught error: ${err}`)
    ))) {
    console.log(value);
    }
  • 使用普通(非 async )生成器,您可以从中手动生成一个又一个 promise ,以便能够以您想要的方式使用它
  • 关于javascript - 异步生成器 : Yielding a rejected promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62395474/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com