2

I am new to JavaScript and I am used to being able to create asynchronous none blocking code in Java by creating worker threads.

I don't understand how asynchronous none blocking code works in JavaScript given that JavaScript is a single threaded language.

For example, Promises and Callbacks in JavaScript.

Both are none blocking, and allow the main thread to keep executing the rest of the program line by line and only when the promise is fulfilled at a later time (ex: data is ready) then the promise.resolve() or a callback is executed.

Now, I am having hard time understanding which thread is exactly keeping track of when the promise is fulfilled/ready or a callback is ready to execute if the main thread has already moved on and is busy doing different things?

My logic tells me as a Java programmer that there must be a background worker thread that is in charge of notifying the main thread when a callback/promise is ready to be executed, which contradicts the fact that JavaScript is single threaded, so I must be wrong.

I would love a nice explanation of this concept. Thanks in advance!

4
  • 1
    It's based on events. The runtime waits for something to happen, and when something happens event handlers are called. Commented Apr 1, 2019 at 21:38
  • The runtimes built on top of JavaScript (like WebAPIs and node.js) are multi-threaded and provide the asynchronous nature. Things like setTimeout are not part of JavaScript, but the runtime. You should look into the event loop and how it works. Commented Apr 1, 2019 at 22:24
  • 1
    Just a note, your two examples are misguided, Promises and callbacks are blocking. Immediately resolved Promises are just pushed to the end of the current execution task, but if you continue resolving Promises directly in a loop, you'll block the whole thread. And it is the task which will call the callback that can be asynchronous, not the callback itself; but this task is also most probably not written in javascript ;-) Commented Apr 2, 2019 at 5:44
  • Thank you all for the very usefull comments, much appreciated! Commented Apr 2, 2019 at 18:46

2 Answers 2

3

There are two ways to achieve concurrent behavior using computers:

  1. You run two computers (or processors) at the same time (multithreading).

  2. You switch between different tasks very fast, so that it looks as if they would run at the same time (multitasking).

Now while Java switches between those tasks very often, JavaScript only switches the task whenever the current task has finished; therefore, the code does not run concurrently and behaves "single-threaded".

That JavaScript is executed in a "single-threaded way" doesn't mean that the underlying engine is single threaded. It isn't and it uses some threads to manage I/O. Whenever you start an asynchronous action, the engine delegates it to one background thread; then, when the task is done the other thread returns the result back to the main thread which will then call back into the JavaScript code.

You could think of the JavaScript engine as a TaskExecutor that starts Threads in a ThreadPool. You do, however, only control the TaskExecutor.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you!! Very nice explanation!
1

Promises / Callbacks are blocking. You may run this example:

function func1() {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log('func1');
      while (true) {}
      resolve();
    }, 0);
  });
}

function func2() {
  func1();
  func1();
  console.log('func2');
}

func2();

You will see func1 is printed only once, because the first executing func1()'s Promise is blocking the second one from being called.

You may consider that each block of codes is placed in THE queue (of event loop).

For asynchronous call, the asynchronous part of the codes is queued, pending for the event loop to run it. Of course, the event loop itself is the single thread in a JavaScript application.

For example, if you move the while loop at the end of func2(), you will never see func1 being printed out, because the function func2() is blocking the queue so that the Promise will never be resolved.

The "thread" which work as the scheduler should be another thread out of the application but since it is not part of the application (written by JavaScript developers / users), I do not think that JavaScript is not a "single threaded language".

1 Comment

Thank you very much for the clarification, very nice example code as well! Much appriciated!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.