How to call a generator (async) function on an interval basis

吃可爱长大的小学妹 提交于 2019-12-11 06:09:14

问题


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

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)

回答1:


Since AdonisJS uses co() under the hood, I used @Bergi suggestion of wrapping in co()

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

var timer = setInterval(() => {
  co(function * () {
    yield sendRequests()
  })
}, 2000)



回答2:


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.

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

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.

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);
}());

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.



来源:https://stackoverflow.com/questions/43099744/how-to-call-a-generator-async-function-on-an-interval-basis

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!