3

In my project I have a very long running operation, so I decided to put it in a Promise because I thought that in this way I could continue to execute the other operations while the code inside the Promise was running.

While debugging, I find out that the code outside the Promise executed only when the code inside the Promise finished executing.

Here is an example of what I'm doing in my project (it simulates a long operation, so it takes a while):

new Promise(function(resolve, reject) {
  var i = 0;
  while (i < 1000000000) {
    i++
  }
  console.log("Executing inside Promise");
});

console.log("Executing outside Promise");

I am not really sure why this is happening and that's why I asked it. But I think that it is somehow related to the fact that the code inside the Promise is synchronous. Indeed when it is async (i.e. the setTimeout() method) it runs after the outside code finishes executing.

new Promise(function(resolve, reject) {
  setTimeout(function() {
    var i = 0;
    while (i < 1000000000) {
      i++
    }
    console.log("Executing inside Promise");
  }, 3000)
});

console.log("Executing outside Promise");

But I still can't figure out why the code inside the Promise is executing synchronously? Shouldn't it execute asynchronously?

Salvatore
  • 499
  • 10
  • 16
  • 2
    Promises don't make synchronous code asynchronous. You typically to use something like `setTimeout()` that is already async inside the promise and the promise just makes it convenient to know when it's done. – Mark Jul 17 '18 at 16:47
  • 1
    As @MarkMeyer said, promises don't make something that's synchronous asynchronous, they just provide a standard way of observing the result of an operation (usually an asynchronous one). But `setTimeout` won't help with that loop, it'll just make it hog the main UI thread at a different time. You'll need a web worker. – T.J. Crowder Jul 17 '18 at 16:50
  • all js code runs sync, it's single-threaded after all. the host must schedule tasks, but code still runs top-down until those escape hatches are reached. – dandavis Jul 17 '18 at 16:58
  • How could the documents (MDN) be any clearer? "The executor function is executed **immediately**" –  Jul 17 '18 at 17:32

1 Answers1

3

The code inside the Promise constructor is meant to run synchronously. A reason for this is that it allows you to do:

var resolve, reject
var p = new Promise(function (res, rej) { resolve = res; reject = rej })
// you can return this `p` from a function or use it with p.then()
// then later
resolve(value)

Note that long running code like your for loop is always blocking, even if you run it inside a setTimeout. If you run it in a timeout it will just block everything else at a different time. The asynchronous part of Promises is useful for I/O things like network request, which require waiting for a result. That for loop doesn't require waiting, in fact it's very very hard at work :). If you need to run expensive code in parallel, you have to use something like Web Workers in the browser or the new worker_threads API in Node.js.

goto-bus-stop
  • 11,655
  • 2
  • 24
  • 31
  • 1
    Thank you for answering @goto-bus-stop Can I use the technology used for networking (along with WebWorkers and worker_threads) to run long operations? What is it? – Salvatore Jul 17 '18 at 18:30