【问题标题】:"Sleep" execution inside asynchronous iteration "for await" (ES2018)“等待”异步迭代中的“睡眠”执行(ES2018)
【发布时间】:2019-03-07 11:35:12
【问题描述】:

我正在使用异步迭代从 DynamoDB 获取项目。对于每次迭代(项目),我都会执行一些 http 请求。为了限制请求流,我需要在每次迭代中“休眠”1 秒。我尝试使用 promisify(setTimeout) 但执行停止。

const sleep = require('util').promisify(setTimeout)

for await (const item of mapper.scan(MyDomainObject)) {

    await sleep(1000);   //This doesn't work
    // do some http requests
}

在“等待”交互中“睡觉”的正确方法是什么?

【问题讨论】:

  • ...你不能使用setTimeout
  • @Stuart 它在 await 中不起作用
  • 我认为你不能在异步循环中优雅地做到这一点。我会将http请求内容添加到队列中,然后迭代地发出这些请求,或者一次两个,或者你想要的任何限制(但异步到循环,因为我假设scan或其他东西很昂贵,如果不是那么让循环异步有点傻)
  • @rtpax 是的,扫描很昂贵(大约 200K 行)。关于您的解决方案的问题是,对于每个循环,我都会执行 20 个请求。这就像 4000 个请求有效负载、标头等存储在内存中,这太多了。我认为它必须是在 for await 中执行此操作的解决方案。
  • mapper.scan 到底是什么?是否支持for await

标签: javascript node.js typescript ecmascript-2018


【解决方案1】:

我想通了。问题是我使用 Jest 执行代码。当我正常执行代码时,上面的代码可以完美运行。感谢 Noseratio 的回答,我在别处看了。我太专注于等待。

【讨论】:

【解决方案2】:

您的代码似乎是正确的,我已经像这样模拟了您的异步生成器:

const sleep = require('util').promisify(setTimeout);

async function* scan(arg) {
  for (let i = 0; i < 4; i++) {
    console.log(`yielding ${i}`);
    await sleep(500);
    yield i;
  }
}

async function test()
{
  for await (let item of scan({})) {
    console.log(`got ${await item}`);
    await sleep(1000);
  }
}

test();

无论我在scan 中提供多少次迭代,执行都不会停止。

因此,导致问题的不是sleep,您应该寻找其他地方。也许,问题出在mapper.scan,或者那些http请求,或者你只需​​要升级你的node.js(我在v10.11.0上)。

【讨论】:

  • 您的回答让我找到了解决方案。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-26
  • 1970-01-01
  • 2017-12-27
  • 1970-01-01
  • 2022-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多