0

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

merito
  • 465
  • 4
  • 15
  • 4
    You need to use await before your sleep ( will only work in async functions). Also, as async/ await are just wrapper for Promises, you just just resolve a Promise after the wait time, otherwise, you're gonna block the main thread – Axnyff Jul 16 '18 at 10:51
  • 2
    Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) (*see heading in answer `ES2017+: Promises with async/await`*). – Igor Jul 16 '18 at 10:52
  • 2
    First thing you need to understand is asynchronous is not threading. – Liam Jul 16 '18 at 10:52
  • why is async_print2 5 seconds? – Keith Jul 16 '18 at 10:55
  • @Liam So what the meaning of asynchronous? IMO, only threading can do asyasynchronous job in OS. – merito Jul 16 '18 at 10:59
  • 1
    Aync code uses one thread that it releases while waiting for async responses. Threading uses multiple threads. Async is like calling someone and asking them to call you back when they have your answer, you then do something else. Threading is using a call centre. Async increases thread utilisation (in IO bound processes) Threading increases CPU utilisation (in CPU bound processes) – Liam Jul 16 '18 at 11:01
  • @Liam I understand, thank you. – merito Jul 16 '18 at 11:19

2 Answers2

3

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.

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

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
Mulan
  • 129,518
  • 31
  • 228
  • 259
  • Thank you. Finally, I understand what **async** means in JS. Without web worker, any user-written JS code will run in main thread, in JS, async just means non-blocking. I actually want two `sleep()` run in other thread, but it's not possible. – merito Jul 17 '18 at 15:35