【问题标题】:Running a function x times asynchronously in a for loop in node在节点的 for 循环中异步运行函数 x 次
【发布时间】:2018-09-30 18:46:30
【问题描述】:

我有一个带有案例的开关,在这种情况下,我想运行 axios.get() X 次,我正在尝试这样做:

          case "visit":
        let i;
        for (i = 0; i < JSON.parse(cmd).contents.threads; i++) {
          let i;
          for (i = 0; i < JSON.parse(cmd).contents.visits; i++) {
            console.log(i + 1 + " visits run!");
            axios.get(JSON.parse(cmd).contents.target).then(res => {});
            if (i === JSON.parse(cmd).contents.visits - 1) {
              console.log("Visiting complete!");
            }
          }
        }
        break;

问题是它不会异步运行并在之后给我结果,输出如下所示:

1 visits run!
2 visits run!
3 visits run!
4 visits run!
5 visits run!
6 visits run!
7 visits run!
8 visits run!
9 visits run!
10 visits run!
Visiting complete!
1 visits run!
2 visits run!
3 visits run!
4 visits run!
5 visits run!
6 visits run!
7 visits run!
8 visits run!
9 visits run!
10 visits run!
Visiting complete!

一次,所以这不是异步运行,有什么建议我应该如何运行这个异步?我正在尝试以这种方式在节点中学习异步,并希望能够做到这一点。

哦,在我忘记之前,这里是 cmd 的 js 对象

 {
  id: "002",
  app: "visit",
  contents: {
    target: "https://google.com/",
    visits: 10,
    threads: 2
  }

【问题讨论】:

  • 接受的答案,虽然它很好地展示了异步代码,但不使用您对线程或任何东西的定义。相反,所有 20 个请求(10 个访问 * 2 个线程)同时运行。如果您对此感到满意,那显然很好,但您知道。

标签: javascript node.js for-loop asynchronous axios


【解决方案1】:

这是因为您的所有输出都在循环的同步执行中发送到控制台。您正在后台启动异步请求,但您不提供在请求完成后执行任何操作的回调。您应该在传递给then() 的函数中输出到控制台。

这是一个例子:

const contents = JSON.parse(cmd).contents;

for (let i = 0; i < contents.threads; i++) {
  let count = 0;

  for (let j = 0; j < contents.visits; j++) {
    axios.get(contents.target).then(result => {
      const number = ++count;

      console.log(number + " visits run!");
      if(number == contents.visits) console.log("Visiting complete!");
    });
  }
}

【讨论】:

    【解决方案2】:

    未经测试

    /////////
    // option 1:
    // To make this run sequentially
    let p = Promise.resolve();
    for (i = 0; i < JSON.parse(cmd).contents.visits; i++) {
      p = p.then(() => axios.get(JSON.parse(cmd).contents.target).then(res => { /* do whatever */});
    }
    p.then(() => {
        //all stuff done
    })
    
    //////
    // option 2:
    // To make this run in parallel (keeping your for loop, etc. (hint: using map would be more concise: 
    const promises = [];
    for (i = 0; i < JSON.parse(cmd).contents.visits; i++) {
      promises.push(axios.get(JSON.parse(cmd).contents.target).then(res => { /* do whatever */}));
    }
    
    Promise.all(promises).then(() => {
        //all stuff done
    })
    

    【讨论】:

    • 我不太明白,这段代码中不包含我的线程键,因此忽略了我试图通过运行函数同时运行访问(比如 100)x3 的事实异步的。因此导致在当前时间跨度的 1/3 内进行 300 次访问,基本上是多线程在 c++ 中的作用(示例)我不太明白你想用你的代码做什么,所以如果你能详细说明会很棒。
    • 啊,我不清楚。所以基本上你想运行 300 个请求,但将并行请求保持在最大 3 个?
    • 是的,抱歉,请阅读我自己不太清楚自己想要做的线程,我现在要测试另一个答案,无论如何感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2019-03-15
    • 2021-09-11
    • 2020-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多