merito
merito

Reputation: 485

How to write async code in JS?

JavaScript is single thread language, which means all user-written code will run in the main thread. For example, in Node.js, the async IO read is an async operation, it runs in a worker thread, but the callback which developer has written run in the main thread as other JS code. So if I identify one JS function with async, it actually did not run in other thread, more important, an async also doesn't mean non-blocking.

const sleep = (wait) => {
  const start = new Date().getTime();
  while (new Date().getTime() - start <= wait) {}
}

const async_print1 = async () => {
  setTimeout(() => {
    sleep(2000);
    console.log('async_print1'); /// in 4s.
  }, 2000);
}

const async_print2 = async () => {
  setTimeout(() => {
    sleep(1000);
    console.log('async_print2'); /// in 5s.
  }, 2000);
}

const sync_print = () => {
  sleep(1000);
  console.log('sync_print'); /// in 1s.
}

async_print1();
async_print2();
sync_print();

The output:

[00:00] <program start>
[00:01] sync_print
[00:04] async_print1
[00:05] async_print2
[00:05] <over>

Fisrt, sync_print run in main thread, it sleep 1s then print. Then, two timer start, after 2s, run loop need call two callback, the two callback both run in main thread, so they're blocking operations.

My question is how to make two sleep() run in other thread? Or just can not?

**Updated my question **

Sorry for my poor english and expression, I finally understand. Thanks you. Is it possible to execute Javascript functions with multi-threads

Upvotes: 0

Views: 342

Answers (2)

Mulan
Mulan

Reputation: 135406

You probably don't need web workers yet. It looks like you forgot await altogether -

const sleep = ms =>
  new Promise (r => setTimeout (r, ms))

const asyncPrint1 = async () =>
{ await sleep (2000)
  console.log ("async print 1")
}

const asyncPrint2 = async () =>
{ await sleep (2000)
  console.log ("async print 2")
}

const syncPrint = () =>
{ console.log ("sync print")
} 

const main = async () =>
{ await asyncPrint1 () // ...2 seconds
  await asyncPrint2 () // ...4 seconds
  await sleep (1000)   // ...5 seconds
  syncPrint ()         
}

main ()
  .then (console.log, console.error)
// async print 1
// async print 2
// sync print

Inside an async function, you can await as many other async calls as you want -

const sleep = ms =>
  new Promise (r => setTimeout (r, ms))
  
const main = async () =>
{ console.log ("begin")
  await sleep (1000)
  console.log ("1 second has passed")
  await sleep (1000)
  await sleep (1000)
  console.log ("3 seconds have passed")
  await sleep (1000)
  await sleep (1000)
  await sleep (1000)
  console.log ("6 seconds have passed")
}

main ()
  .then (console.log, console.error)
  
// begin
// 1 second has passed
// 3 seconds have passed
// 6 seconds have passed
// undefined

Upvotes: 1

Quentin
Quentin

Reputation: 944320

There is no way to turn synchronous code into asynchronous code. If the event loop is busy running your while loop (which is blocking code), then it is going to be too busy to do anything else. The async keyword just makes a function return a promise (and allows you to use await inside it).

You can shunt code off into another thread using Web Workers.

Upvotes: 3

Related Questions