0

Could someone try and help me to understand why the first function is non-blocking while the second one blocks the rest of the code? Isn't Promise.resolve the same as resolving from a new Promise? I can't quite wrap my head around it.

function blockingCode() {
  return new Promise((resolve, reject) => {
    for (let i = 0; i < 2500000000; i++) {
      // Doing nothing...
    }
    resolve('ping');
  });
}

function nonBlockingCode() {
  return Promise.resolve().then(() => {
    for (let i = 0; i < 2500000000; i++) {
      // Doing nothing...
    }
    return 'pong';
  });
}

console.time('non-blocking');
nonBlockingCode().then((message) => console.log(message));
console.timeEnd('non-blocking');

// console.time('blocking');
// blockingCode().then((message) => console.log(message));
// console.timeEnd('blocking');
Gerard
  • 15,418
  • 5
  • 30
  • 52
David
  • 99
  • 6
  • 4
    That's not quite right. They both block while the loop is executing. The only difference is when the returned promise resolves. Also, `.then((message) => console.log(message))` can just be `.then(console.log)` – Jared Smith Nov 09 '21 at 12:31
  • 1
    The names of your functions are confusing given the content of the question. – Pointy Nov 09 '21 at 12:35
  • Please note that promises is not concurrency, although it does enable it (using things like workers) – evolutionxbox Nov 09 '21 at 12:36
  • 1
    @evolutionxbox they are indeed *concurrent*, they are not *parallel*. – Jared Smith Nov 09 '21 at 12:38
  • @evolutionxbox no prob. [legendary explanation of the difference](https://stackoverflow.com/questions/34680985/what-is-the-difference-between-asynchronous-programming-and-multithreading/34681101#34681101) – Jared Smith Nov 09 '21 at 12:41
  • Your first function is equivalent to `for (let i = 0; i < 2500000000; i++) {} return Promise.resolve('ping');` – Bergi Nov 09 '21 at 20:58

1 Answers1

2

The two functions are actually blocking.

You have the illusion that the second one isn't blocking because calling Promise.resolve().then() adds one more round to the event loop, so console.timeEnd('non-blocking'); is reached before the code inside your promise even starts.

You will notice that both function block if you fix your code like this:

console.time('non-blocking');
nonBlockingCode()
.then((message) => console.log(message))
.then(() => console.timeEnd('non-blocking'));

Note that a promise is intended not to block when the time-consuming logic inside the promise is delegated to a third-party, and you just wait for the result (e.g. when a client does a call to a remote database, a remote web server, etc.).

If you are having a hard time with promises and then logic, have a look at the async / await syntax, I find it much easier to understand.

Jean-Baptiste Martin
  • 1,399
  • 1
  • 10
  • 19