Promise.allSettled 永远卡住

时间:2021-03-21 14:52:46

标签: javascript

我使用 Promise.allSettled 以批量方式获取网站。如果我将网站列表的大小限制为 10,它可以正常工作,但是一旦我将其增加到 1000,它就会卡住。

这很奇怪,我从未发生过。我已经等了三天直到脚本完成,但它仍然停留在前 1000 项。

const rp = require('request-promise');
const lineReader = require('line-by-line');

const reader = new lineReader("./all.json");

let lines = [];
const limit = 1000;

let successCount = 0;

reader.on('line', async (line) => {
    line = JSON.parse(line);

    lines.push(line);

    if (lines.length === limit) {
        reader.pause();

        let promises = [];

        for (const line of lines) {
            promises.push(rp(line.website))
        }
    
        await Promise.allSettled(promises);

        successCount++
        console.log(`Success Count is ${successCount}`);

        lines = [];

        reader.resume();
    }
});

data.json 文件具有以下格式的网站列表,

{ website: "https://www.google.com" }
{ website: "https://www.bing.com" }
{ website: "https://www.microsoft.com" }

您可以通过将类似 { website: "https://www.google.com" } 的行复制 2000 次来重现该行为。

1 个答案:

答案 0 :(得分:0)

解决方案是用一个承诺在一定时间后超时来结束我的承诺。

这里是提供超时承诺能力的函数,

const withTimeout = (millis, promise) => {
    const timeout = new Promise((resolve, reject) =>
        setTimeout(
            () => reject(`Timed out after ${millis} ms.`),
            millis));
    return Promise.race([
        promise,
        timeout
    ]);
};

你可以像下面一样使用它,

await Promise.allSettled([
   withTimeout(5000, rp("https://www.google.com"),
   withTimeout(5000, rp("https://www.bing.com"),
]));

我知道您可以在 request-promise 选项中指定超时,但由于某种原因它对我不起作用,但我在添加它时注意到了某些改进。