Promise.allSettled 永远卡住

jef*_*RTC 5 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();
    }
});
Run Code Online (Sandbox Code Playgroud)

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

{ website: "https://www.google.com" }
{ website: "https://www.bing.com" }
{ website: "https://www.microsoft.com" }
Run Code Online (Sandbox Code Playgroud)

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

jef*_*RTC 7

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

这是提供超时功能的函数,

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

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

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

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