regenerator
regenerator copied to clipboard
[bug?] `await null` inside while loop causes infinite loop?
Based on the discussion at https://github.com/facebook/regenerator/issues/236, await
should always defer. However, I seem to have found bug?
The following example behaves as if the await null
line doesn't defer, causing the while loop to loop forever and crashing the browser tab. The first console.log
inside of main()
fires, which indicates control leaves the while loop and goes to regenerator, but then regenerator never routes control away from the while loop to the second console.log
:
class TickCounter {
constructor() { this.current = -1 }
async start() {
this.shouldCount = true
while (this.shouldCount) {
this.current += 1
await null
}
}
stop() { this.shouldCount = false }
}
const sleep = time => new Promise(r => setTimeout(r, time))
async function main() {
let counter = new TickCounter
counter.start()
console.log('current tick:', counter.current) // is 0
await sleep(0)
// these lines never fire.
console.log('current tick:', counter.current) // was expecting 1
counter.stop()
}
main()
A simple reproduction can be found here, in client/main.js
: https://github.com/trusktr/site/tree/regenerator-issue-236
To run, just
git clone [email protected]:trusktr/site.git
cd site
git checkout regenerator-issue-236
meteor
When visiting localhost:3000
, the page will freeze.
@benjamn Got a chance to look at this yet? The issue is reproducible, it's a simple Meteor 1.3.1 app.
On a related note, I discovered that code following the await of a promise inside of a requestAnimationFrame
loop fires within the same frame, which makes it seem like Promise settling is happening synchronously.
Here is the code: https://esdiscuss.org/topic/promises-async-functions-and-requestanimationframe-together
I was under the impression that since Promises should settle asynchronously, that the code in the loop would fire outside of the animation frame, not inside. Can you offer any insights on what's happening with that animation loop and why the code, which I thought would be deferred, still fires inside the animation frame? I guess I'm asking: what is the behavior we should expect (and how does it compare to what I'm seeing in practice)?
TLDR, writing an animation loop like that, using while
, is nice in concept and and in how the code reads, but I'd like to avoid it if the behavior that I am experiencing (all logic fires in the frame) isn't what will actually happen when async
functions become native in browsers.
Cheers!