异步生成器:产生被拒绝的承诺

问题描述 投票:2回答:1

我一直在尝试使用异步生成器,以尝试创建一个“承诺排序”生成器,该生成器接受一组承诺并以它们分解或拒绝的顺序逐个产生承诺。像这样:

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);
    }
})()

但是,我注意到这将达到第二个承诺,然后发电机将停止。这似乎是因为被拒绝的“第二”承诺。在yield prom被拒绝时,在生成器中调用prom将创建异常在生成器中

但这是我困惑的根源。我不想在这里创建异常,我只想将被拒绝的诺言作为迭代器结果的value。我不希望将其打开。几乎就像将其视为yield await prom;,但是您可以看到没有await调用。

这里发生了什么,我怎么能直接从此生成器中产生被拒绝的诺言。


以下为可运行代码段中的上述代码:

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);
    }
})()

[我一直在与异步生成器一起玩耍,试图制作一个“承诺排序”生成器,该生成器接受一组诺言,并按照它们解析或...的顺序逐个产生诺言。...

javascript promise async-await generator async-iterator
1个回答
0
投票
几乎就像将其视为yield await prom。这是怎么回事?
© www.soinside.com 2019 - 2024. All rights reserved.