问题
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