Promises executor dominates over timeouts
See original GitHub issueFirst, some table-setting:
var canceled = false;
const loop = () => {
if (!canceled) {
console.log("looping");
new Promise((resolve, reject) => loop());
}
};
setTimeout(() => { console.log("canceling"); canceled = true; }, 5);
loop();
This does what you would expect: it loops for a while and then cancels.
So does the following:
import scala.concurrent.ExecutionContext
import scala.concurrent.duration._
import scala.scalajs.concurrent.QueueExecutionContext
import scala.scalajs.js.timers
object Test {
def main(args: Array[String]): Unit = {
var cancel = false
val exec: ExecutionContext = QueueExecutionContext.timeouts()
def loop(): Unit = {
if (!cancel) {
println("looping")
exec.execute(() => loop())
}
}
timers.setTimeout(5.millis) { println("canceling"); cancel = true }
loop()
}
}
Again, loops for a little while and then cancels.
This, however, loops forever:
import scala.concurrent.ExecutionContext
import scala.concurrent.duration._
import scala.scalajs.concurrent.QueueExecutionContext
import scala.scalajs.js.timers
object Test {
def main(args: Array[String]): Unit = {
var cancel = false
val exec: ExecutionContext = QueueExecutionContext.promises() // <---- this is the only difference!
def loop(): Unit = {
if (!cancel) {
println("looping")
exec.execute(() => loop())
}
}
timers.setTimeout(5.millis) { println("canceling"); cancel = true }
loop()
}
}
It appears that if any outstanding work is available on the promises
queue, it will dominate over the timeouts queue. My guess without looking at the code is that this is a consequence of a well-intentioned optimization within ScalaJS itself which fails to yield, since it definitely doesn’t reproduce within Node.
Issue Analytics
- State:
- Created 3 years ago
- Comments:49 (27 by maintainers)
Top Results From Across the Web
Why Promises Are Faster Than setTimeout()? - Dmitri Pavlutin
The experiment has demonstrated that an immediately resolved promise is processed before an immediate timeout. The big question is... why? 2.
Read more >Execution order of Timeout and Promise functions(Main Tasks ...
I think output one and four are pretty clear. setTimeout is a part of Main Task queue while Promise is of Micro task...
Read more >SetTimeout vs Promises - Medium
I'll make a step by step analysis of the code execution. 1. The call stack executes setTimeout(..., 0) and schedules a timer. timeout()...
Read more >Promise.all() - JavaScript - MDN Web Docs
Promise.all is rejected if any of the elements are rejected. For example, if you pass in four promises that resolve after a timeout...
Read more >In what situation should I use a promise over a timeout ... - Quora
You should never use timeout instead of a promise, they do not serve the same purpose. Promise allows you to associate handlers with...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
The above project now contains the polyfill executor implementation, as well as almost all the associated testing and CI infrastructure. The only thing it’s missing at present is the infrastructure for testing under webworker environments, which we’re working on.
Incidentally, doing this uncovered the fact that the polyfill is not working on jsdom. It doesn’t fail anything, but it falls back to
setTimeout
(with the associated clamping). We’ll see if that’s fixable (seems doable, sincepostMessage
should be present in that environment).Plan of record here is the following: https://github.com/typelevel/cats-effect/issues/2314
I created https://github.com/scala-js/scala-js-macrotask-executor and added you as a maintainer.
I’ll leave it up to @sjrd how to organize permissions.