在节点的for循环中异步运行函数x次

时间:2018-09-30 18:46:30

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

我有一个带有大小写的开关,在这种情况下,我想运行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
  }

2 个答案:

答案 0 :(得分: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!");
    });
  }
}

答案 1 :(得分:0)

未经测试

/////////
// 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
})