如何定期调用生成器(异步)函数 [英] How to call a generator (async) function on an interval basis

查看:76
本文介绍了如何定期调用生成器(异步)函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个必须每2秒轮询一次远程设备(生成器fn sendRequests())的应用.

I am building an app that must poll remote devices (generator fn sendRequests()) every 2 seconds.

使用setInterval调用生成器fn的正确方法是什么,它不是生成器,也不产生结果

What's the right way to call the generator fn using setInterval, which isn't a generator and doesn't yield

function * sendRequests() {
  // multiple remote async requests are sent
}

var timer = setInterval(() => {
  // yield sendRequests()
}, 2000)

推荐答案

setInterval 回调产生的问题是 yield 只能屈服于生成器功能* 立即包含它.因此,您无法从回调中 yield .

The problem with yielding from the setInterval callback is that yield can only yield to the generator function* that immediately contains it. Therefore, you can't yield from a callback.

您可以通过回调来解决一个Promise,您的生成器函数可以对该Promise进行 yield :

What you can do from a callback is resolve a Promise, which your generator function can yield:

async function* pollGen() {
  yield new Promise((resolve, reject) => {
    setInterval(() => resolve(...), 2000);
  });

问题在于承诺只能解决一次.因此,每隔2000ms调用一次 resolve 将不会执行任何操作.

The problem with that is a Promise can only be settled once. Therefore, calling resolve every 2000ms won't do anything beyond the first call.

相反,您可以做的是在while循环中重复调用 setTimeout :

What you can do instead is call setTimeout repeatedly, in a while loop:

async function* pollGen() {
  let i = 0;
  while (i < 10)
    yield new Promise((resolve, reject) => {
      setTimeout(() => resolve(i++), 200);
    });
}

(async function main() {
  // for-await-of syntax
  for await (const result of pollGen())
    console.log(result);
}());

新的 for-await-of 语法自Node v9.2起可用,并且可以在Nodev10或更高版本中使用而没有任何标志.

The new for-await-of syntax has been available since Node v9.2, and can be used in Node v10 or later without any flags.

这篇关于如何定期调用生成器(异步)函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆