【问题标题】:Javascript: simulate random execution time for the same functionJavascript:模拟相同函数的随机执行时间
【发布时间】:2021-08-09 04:05:31
【问题描述】:

我有一个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;
}

如何更改它以实现与上述示例类似的输出?

【问题讨论】:

  • 看看异步函数,当被调用时发生在一个单独的线程developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 呃,不,@StarshipladDev,你走错了路。异步函数在单独的线程中运行。它只是语法糖。除非您使用工作线程,否则 JS 仍然是单线程的。而且,如果有的话,异步允许您在异步函数上 await,即,使它们再次显示为同步,这与 OP 想要的相反。

标签: javascript node.js asynchronous synchronous


【解决方案1】:

将您的外部逻辑提炼到基本要素会使错误更加明显:它是输出中使用的计数器,当您增加它时。运行此规范示例:

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

【讨论】:

  • 谢谢!意识到问题了!
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2012-08-02
    • 2021-06-30
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-25
    相关资源
    最近更新 更多