2

In this document: MDN - Promise() constructor

there is a phrase:

  1. The operation within executor is asynchronous and provides a callback.

And here is code

console.log('before promise');
new Promise(function(resolve, reject) {
  console.log('promise');


  let j = 0;
  for (i = 0; i < 1000000000; i++) {
    j++;
  }
  resolve(1);
  console.log('promise end');

}).then(function() {
  console.log('then');
});

console.log('not promise but after');

It displays in console

  • before promise
  • promise
  • promise end
  • not promise but after
  • then

I thought once operation within executor is asynchronous, then Javascript should not wait for finish of code within executor , and "not promise but after" should be displayed right after "before promise". But it seems i do not understand meaning of this phrase. Can please someone explain what does it mean?

Yousaf
  • 27,861
  • 6
  • 44
  • 69
olevacho
  • 23
  • 5
  • 2
    Executor function is executed synchronously. Promises are not used to make something asynchronous; they are wrappers around _already asynchronous_ operation which notify you whether the _already asynchronous_ operation finished successfully or whether it failed. – Yousaf Jul 19 '21 at 09:47
  • 1
    promises do not automatically enable multi-threading. You're blocking the main thread, promises will not help here – evolutionxbox Jul 19 '21 at 09:47
  • 1
    @evolutionxbox JavaScript is single threaded. It's concurrency: [Why doesn't JavaScript support multithreading?](https://stackoverflow.com/questions/39879/why-doesnt-javascript-support-multithreading) –  Jul 19 '21 at 09:48
  • To do something like this, you'd have to wait in the middle. Instead of new Promise you could use an async function and place an `await new Promise(r => setImmediate(r))` inside the loop. – CherryDT Jul 19 '21 at 09:49
  • Usually MDN has good documentation, but in this case, it is of low quality I must say. The executor is executed *synchronously*. It has more misleading info, like "The callback terminates by invoking resolutionFunc". This is not true; execution continues even after calling the `resolutionFunc`. I don't know who wrote this, but that person should be stopped from editing MDN. – trincot Jul 19 '21 at 09:49
  • 1
    @jabaa yes. my point is that promises does not enable it. we agree here – evolutionxbox Jul 19 '21 at 09:49
  • @evolutionxbox Yes, I'm sure you meant the correct thing but in this case I'm nitpicky. The wording could be misleading for some people and they could think that JavaScript supports multithreading. –  Jul 19 '21 at 09:51
  • @jabaa . But it seems Web Workers implement multi-threading – olevacho Jul 20 '21 at 09:40
  • @olevacho The language JavaScript is single threaded. Of course you can start a new process and use messages to let them communicate but JavaScript is single-threaded and each process is single-threaded. A Web Worker is also single-threaded. That's a completely different concept to a language with multithreading support where you have to synchronize your threads. –  Jul 20 '21 at 09:42
  • they already changed the wording on MDN – Antoine Weber Apr 17 '23 at 21:51

2 Answers2

2

Let's look at the the context around what you quoted:

And so, given all the above, here’s a summary of the typical flow:

  1. The operation within executor is asynchronous and provides a callback.

MDN is describing a typical flow.

The operation in the executor that you passed to the Promise constructor is not asynchronous (which making using a Promise pointless).

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
1

The promise executor is run synchronously – in the case of an async function, up until the first await within it.

If you wanted something like your use case, i.e. doing lots of synchronous computation but occasionally yielding to let other things happen, you could make your function async and have it wait (setTimeout here; could be the non-standard setImmediate) every now and then.

You can also do this without using async, but it's a bit of a pain to get right.

const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

async function doThings() {
  console.log("promise");
  let j = 0;
  for (i = 0; i < 1000000000; i++) {
    j++;
    if (i && i % 100000 == 0) await delay(0); // magic yield
  }
  console.log("promise end");
  return j;
}

console.log("before promise");
doThings().then(function () {
  console.log("then");
});
console.log("not promise but after");
AKX
  • 152,115
  • 15
  • 115
  • 172