Javascript:模拟同一个函数的随机执行时间

Javascript: simulate random execution time for the same function

我有一个 askGoogle 功能。我循环调用它 10 次。我想这样做,所以每次调用该函数都需要随机的时间。以便某些调用先完成:

Done with google 0
Done with google 3
Done with google 2
Done with google 8
Done with google 1
...

但是我不确定该怎么做。我试图用 setTimeout 方法模拟它,但它似乎强制代码同步运行,因此所有对 askGoogle 的下一次调用都等到上一次调用完成。

const https = require("https");

let i = 0;
function askGoogle()  {
    setTimeout(() => {

        const googleRequest = https.request("https://google.com", {
            method: "GET"
        });
        googleRequest.once("error", err => {
            console.log("Something happened!");
        })
        googleRequest.once("response", (stream) => {
            stream.on("data", x => {
            });
            stream.on("end", () => {
                console.log("Done with google " + i);
                i++;
            })
        })
        googleRequest.end();
    }, getRandomInt(0, 50_000));
}


for (let j = 0; j < 10; j++) {
    askGoogle();
}

function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

如何更改它以获得类似于上面示例的输出?

您的 stream.on("end", ...) 闭包将始终按顺序打印“0, 1, 2,...”,即使 googleRequest 调用是乱序的。

快速修复:

let i = 0;
function askGoogle()  {
    let j = i++;  // This way we are sure we are counting in order of calling askGoogle
    setTimeout(() => {

        const googleRequest = https.request("https://google.com", {
            method: "GET"
        });
        googleRequest.once("error", err => {
            console.log("Something happened!");
        })
        googleRequest.once("response", (stream) => {
            stream.on("data", x => {
            });
            stream.on("end", () => {
                console.log("Done with google " + j);. // j has been fixed before
            })
        })
        googleRequest.end();
    }, getRandomInt(0, 50_000));
}


for (let j = 0; j < 10; j++) {
    askGoogle();
}

将您的外部逻辑提炼成基本要素会使错误更加明显:它是输出中使用的计数器以及何时增加它。 运行 这个典型的例子:

let i = 0;
function askGoogle()  {
    setTimeout(() => {
      console.log("Done with google " + i);
      i++;
    }, getRandomInt(0, 500));
}

for (let j = 0; j < 10; j++) {
    askGoogle();
}

function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

我建议将 j 作为参数传递给 askGoogle 函数并打印它。

let i = 0;
function askGoogle(j)  {
    setTimeout(() => {
      console.log("Done with google " + j);
    }, getRandomInt(0, 500));
}

for (let j = 0; j < 10; j++) {
    askGoogle(j);
}

function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min;
}