-
Notifications
You must be signed in to change notification settings - Fork 362
Description
After an asynchronous call is completed in an AsyncFunction, you pass your result back to the interpreter using the supplied callback function, then you need to resume stepping the state stack somehow, often via interpreter.run() if you're not using an external stepper.
For example:
function nativeAsyncFunction(val, callback) {
setTimeout(() => {
callback(val)
interpreter.run() // Continue stepping
}, 0)
}
If, however, your AsyncFunction ends up not doing an asynchronous call for whatever reason and just executes the callback, if you mistakenly execute interpreter.run() again you'll throw things off, since the existing loop in interpreter.run() was never broken by the asynchronous call.
For example:
function nativeAsyncFunction(val, callback) {
callback(val)
interpreter.run() // This will do bad things
}
Sometimes it can be difficult to track whether your AsyncFunction actually did an asynchronous operation or not, especially if it's calling other functions in 3rd party libraries that may or may not end asynchronously.
It would be nice to have run() keep track of its run state. Perhaps by changing the run function to something that will block execution if it's already running, like:
Interpreter.prototype.run = function() {
if (this.running_) return this.paused_
this.running_ = true
try {
while (!this.paused_ && this.step()) {}
} catch (e) {
this.running_ = false
throw e
}
this.running_ = false
return this.paused_
}