JavaScript and Java have totally different approaches to asynchrony. While Java has thread based concurrency, were the same code can run across different threads and works on the same memory, JS has task based concurrency with different agents that can exchange messages with each other.
Therefore you cannot just translate a thread based coding style into a task based one.
Task based concurrency: Thread based concurrency:
- time -> ---- time --> - time -> - time -> - time ->
+-------+ +-------+ +-------+ +----------+ +----------+ +-----------+
| Task | | task | | task | | Thread | | Thread | | Thread |
+-------+ +-----------------+ +--------------------------------------+
| Agent |<-Msg ->| Agent | | Engine |
| -Code | | -Code | | -Code |
| -Mem | | -Mem | | -Mem |
+----------------------------------+ +--------------------------------------+
| Engine |
+----------------------------------+
In most cases, one agent is enough in JavaScript, as you can offload most tasks (timers, IO) onto the engine:
setTimeout(function() { // Task 1: Register the timer
// Task 2: Do stuff when the timer triggers
console.log("test");
}, 1000);
The only case were you would really need more than one agent, is if you have work that you cannot offload, so in other words: Heavy computations. In those cases you can use multiple agents (WorkerThreads / ServiceWorkers in browsers, processes in NodeJS). These agents, unlike Java threads, don't share code and memory (except for SABs).
To get another WebWorker running in the browser, you have to start one specifying another file to run:
const worker = new WebWorker("worker.js");
Then you can send/receive messages between the agents.