运行for循环并暂停api调用

时间:2019-09-08 11:35:49

标签: javascript

我正在使用node v10.15.3,并且试图暂停4 seconds进行api调用。

我尝试了以下操作:

let arr = ["Product 1", "Product 2", "Product 3", "Product 4"]


function callApi() {
  console.log("start - " + new Date().toString());
  for (var i = 0; i <= arr.length; i++) {
    (function(index) {
      setTimeout(async() => {
        // here usually comes the api call
        await console.log(arr[index]);
        await console.log(new Date().toString());
      }, 4000);
    })(i);
  }
  console.log("end - " + new Date().toString());
}

callApi()

从输出中可以看到,首先输出消息startend,然后运行for-loop。但是,我想在每个函数运行4秒之间等待并获得以下输出:

start - Sun Sep 08 2019 13:28:03
Product 1
Sun Sep 08 2019 13:32:07
Product 2
Sun Sep 08 2019 13:36:07
Product 3
Sun Sep 08 2019 13:40:07
Product 4
Sun Sep 08 2019 13:44:07
end - Sun Sep 08 2019 13:28:03

任何建议我做错了。

3 个答案:

答案 0 :(得分:2)

setTimeout(..., 4000)-在循环的每次迭代中,您调用setTimeout的功能均不同,但延迟相同,因此计划将这四个功能从现在起4秒同时运行。 / p>

相反,请尝试:setTimeout(..., 4000 * (index + 1))

或者,由于您已经在使用await,因此可以通过将setTimeout包装在Promise中来更清楚地编写此代码:

let arr = ["Product 1", "Product 2", "Product 3", "Product 4"]

function sleep(ms) {
  return new Promise(resolve => {
    setTimeout(resolve, ms);
  });
}

async function callApi() {
  console.log("start - " + new Date().toString());
  for (let i = 0; i <= arr.length; i++) {
    await sleep(4000);
    console.log(arr[i]);
    console.log(new Date().toString());
  }
  console.log("end - " + new Date().toString());
}

callApi()

旁注:awaitconsole.log一起使用时无效,因为后者不会返回Promise(也许您以前有与网络相关的代码,在这里确实使用了promise,这只是剩菜吗?)。

答案 1 :(得分:2)

仅在await循环主体中使用for可能更有意义:

let arr = ["Product 1", "Product 2", "Product 3", "Product 4"];
const delay = ms => new Promise(res => setTimeout(res, ms));

async function callApi() {
  for (const item of arr) {
    await delay(2000); // example API call
    console.log(item);
  }
}

callApi()

答案 2 :(得分:2)

async函数是一个能够停止执行代码并能够await解决异步任务(通常是一个承诺)的功能。由于您的for loop位于外部函数(不是异步函数)中,因此它将无需等待任何内容即可完成循环,只需启动几个独立的setTimeout

要修复您的函数,请像下面这样重写它:

  async function callApi() {
    for (var i = 0; i <= arr.length; i++) {
      // here usually comes the api call
      await request(i)
    }
  }

  function request(i) {
    return new Promise((resolve) => {
      setTimeout(() => {
        console.log(i);
        resolve();
      }, 4000);
    }
  }

“暂停”功能背后的功能称为generators,以备您了解其工作原理。