javascript - 如何在 forEach 循环中每秒运行一次 setTimeout?

标签 javascript loops foreach async-await settimeout

我的代码是为了在每分钟有 60 次写入限制的在线服务中创建多个展示位置:

  placementsToAdd.forEach((placement, index) => {
    setTimeout(() => {
      options.url = `https://api.company.com/placement?publisher_id=${existingPub ? existingPub : placementsJson[0].PublisherId}&site_id=${placement.siteId}`
      options.body = `{"placement":{"name":"${placement.placement}"}}`
      request(options, callback);  
    },1000 * (index + 1))
  })

它是这样工作的,但我担心等待时间,如果一次有 2000 或 3000 个展示位置列表,等待时间可能会过长。

有没有更好的方法来重构此代码,以便无论如何都能每秒生成一个请求?没有那个“* (index + 1)”,它似乎一直在尝试一次构建所有内容,在 60 之后碰壁。

我尝试使用 promises 和 async await(这对我来说是新手),但它似乎并没有改变行为。

谢谢!

按照要求,展示我是如何尝试在这段代码中使用 promises 的:

  async function createThePlacements() {
    let promise = new Promise((resolve, reject) => {
      for (let i = 0; i < placementsToAdd.length; i++) {
        setTimeout(() => {
          options.url = `https://api.company.com/placement?publisher_id=${existingPub ? existingPub : placementsJson[0].PublisherId}&site_id=${placementsToAdd[i].siteId}`
          options.body = `{"placement":{"name":"${placementsToAdd[i].placement}"}}`
          request(options, callback);  
        },1000)
      }
    });

    let result = await promise; // pause till the promise resolves 
    console.log('result - ', result);
  }

  createThePlacements();

因此,有点免责声明 - 如前所述,我之前从未使用过 Async Await,因此请继续阅读以尝试了解它的工作原理。这似乎是语法,但我的结果目前似乎没有任何结果,但代码也继续做它应该做的事情,只是试图一次完成我的 300 测试中的所有调用。

另外,值得注意的是,我在请求调用的回调中有一个解析。它解决了,所以即使我的应用程序的下一部分也一直完成到最后。这就是为什么我在这里没有拒绝或解决的原因。

最佳答案

How do you run a setTimeout once a second inside a forEach loop?

最直接的方法是:

const wait = ms => new Promise(resolve => setTimeout(resolve, ms));

for (const placement of placementsToAdd) {
  const options = {...};
  request(options, callback);  
  await wait(1000);
}

await 在普通 for 循环中可预测地工作,而不是在 forEach 中。

我没有触及您的回调,但它需要处理错误。更多的重构是可能的。

我认为这里最重要的改进是我们没有提前推送请求。通过这种方式,我们可以保留控制权,如果需要更改或出现任何问题,我们可以跳出循环,而不会再向服务器发送垃圾邮件一分钟。

关于javascript - 如何在 forEach 循环中每秒运行一次 setTimeout?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55668900/

相关文章:

python - 通过在 Python 中循环行来连接

foreach - 在 Erlang 中理解和使用 foreach

javascript - for循环没有正确执行http服务

javascript - 使用 jQuery Hover 更改 css 样式

javascript - 使用map,如何将对象属性中的yes和no字符串转换为javascript中的 bool true和false值

javascript - 超时不断变化的无限循环

javascript - 在检查子复选框时检查父复选框

arrays - 遍历不同大小的数组

c# - 传递 DataGridViewRow 作为引用

c# - IEnumerable 是否需要使用 foreach 循环?