4

I don't understand how to work with asynchronous functions.

Why does the code below stop the main thread?

async function foo() {
  for (;;) {}
}
foo();
Ivar
  • 6,138
  • 12
  • 49
  • 61
  • Check this https://stackoverflow.com/questions/11488014/asynchronous-process-inside-a-javascript-for-loop – Tasos Kakouris Feb 01 '19 at 11:11
  • 3
    Asynchronous code does not mean multithreaded, the code still runs in one thread. Async is just some kind of cooperative multitasking, but not multithreading. – t.niese Feb 01 '19 at 11:11
  • 1
    @Ivar — Most modern JS implementations support a form of threads these days. It's just that the `async` keyword isn't that. – Quentin Feb 01 '19 at 11:15
  • browsers have an event loop. when you calling an async function, the function will be scheduled to be run in the next loop, but still is single threaded. – behzad besharati Feb 01 '19 at 11:27
  • @behzadbesharati calling an `async` function does not schedule is execution. It will be executed immediatly (as you can see in this [fiddle](https://jsfiddle.net/gw2bx9to/) ). The returned Promise is resolve at a later state. – t.niese Feb 02 '19 at 20:05
  • it will be executed immediately (after current loop execution finished). So, yeah In current loop you will get a promise. In the further loops your promise will be resolved. – behzad besharati Feb 03 '19 at 04:00
  • @behzadbesharati `(after current loop execution finished).` no the function is executed immediately at the time it is called (otherwise the output of my example in the fiddle would be `1 3 2` an not `1 2 3`). `async` does not change anything about when the called function is executed, `async` only enforces that the function returns a Promise, an uncaught error in the function is passed using that Promise, and that `await` can be used. – t.niese Feb 03 '19 at 06:45

2 Answers2

13

The async keyword, and promises in general, don't make synchronous code asynchronous, slow running code fast, or blocking code non-blocking.

async just makes the function return a promise and provides (with the await keyword) a mechanism to interact with other promises as if there were synchronous.

Your function starts a loop, and then just goes around and around.

It doesn't get to the end of the function, which would end the function and resolve the promise it returned.

It doesn't reach an await keyword and pause while it waits for the awaited promise to be resolved.

It just goes around and around.

If you were actually doing something in the loop which was computationally expensive and you wanted to push off into the background, then you could use a Node.js Worker Thread or a browser-based Web Worker to do it.

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

Putting the async keyword before the function only implies that this is asynchronous function. You need to include the keyword await before the function that you want to actually wait for. Just like this:

async function hashPin(pin){
    const hashedPin = await bcrypt.hash(pin, saltRounds);
}

That's just the example from one of my projects (the redundant code has been removed before posting)

Irek
  • 187
  • 2
  • 12
  • Good, this one works for me. –  Feb 01 '19 at 11:15
  • 1
    I'm not sure why this would work because an infinite loop will still be blocking. – Ivar Feb 01 '19 at 11:33
  • 1
    `async` in front of the function serves two purposes. 1. it enables usage of `await` in the function. 2. it tells the caller that it is guaranteed that this function returns a Promise. But neither `async` nor `await` do magically resolve blocking issues. So if `bcrypt.hash` has some blocking code in it, then `await` in front of it would not resolve that blocking issue. And removing the `await` and writing `async function hashPin(pin){ return bcrypt.hash(pin, saltRounds).then( hashedPin => /*...*/)}` would not make a difference regarding blocking. – t.niese Feb 01 '19 at 11:37
  • 1
    You guys are right, I totally missed the bit about infinite loop and only provided an answer to how to work with asynchronous functions. My bad – Irek Feb 01 '19 at 11:42