0

I am new to asynchronous code in general (and JavaScript in particular) and have been falling prey to common pitfalls, so I want to re-evaluate my most basic assumptions.

Testing the code below does not give me an answer since, just because the test passed, doesn't mean the code will run the same way in the future.

The question is very general, so I will give a couple concrete examples of the basics I am trying to understand.

First Example

const secret_key = "BLAH BLAH";
var url = `https://www.google.com/recaptcha/api/siteverify?secret=${secret_key}&response=${token}`;

If the above code occurs in an async function, can I be sure that url will be defined correctly (i.e. that the second statement will occur after the first)? Does this change if secret_key is a var? Or let?

Second Example

blah = async function() {
    syncFunction();
}

Can I be certain that the synchronous function will be run to completion before the function returns (even if it has to do some time-intensive work)?

I ask because my understanding is that this would not be true for an asynchronous function (as explained here) unless I use await / promises.

Update

In the end, this Stack Overflow question resolved my problem. Basically I was using await, but the function being called had an undefined Promise.

Philip H
  • 300
  • 1
  • 17
  • 1
    Yes, no, no, yes. Specifically in the last part the async function cannot finish before `syncFunction` has fully run, note that you do not actually invoke a function in that snippet at all, you simply define a new function into `blah`, `syncFunction` is in fact not called at all here. – luk2302 Mar 10 '21 at 09:24
  • @luk2302 Can you elaborate on the last part (i.e. `syncFunction` is in fact not called at all here)? Maybe a better example would be `if (syncFunctionReturnsFalse()) { return false; } // do other stuff`... I want to make sure the if statement waits for the synchronous function. – Philip H Mar 10 '21 at 09:36
  • you only declare / define a function, you never run it, `blah` *is* the function, it is not its promise or its return value, it *is* the function, only `blah()` would then actually run it. – luk2302 Mar 10 '21 at 09:38
  • if course it waits, it cannot not wait. – luk2302 Mar 10 '21 at 09:40
  • Ah, I see what you mean - I omitted the call to `blah();` (I treated the call as implicit).And you say "the async function cannot finish before `syncFunction` has fully run" and "of course it waits" but this is NOT true for an async function call, much to my surprise (assuming I understand that article correctly). – Philip H Mar 10 '21 at 09:47
  • No, you are mixing async stuff and aws lambda stuff. The lambda simply does not wait for `blah` if it is async, unless you tell it to. – luk2302 Mar 10 '21 at 09:49
  • Does this answer your question? [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Liam Mar 12 '21 at 11:21
  • @Liam This is very close, and also links to other helpful questions I looked at (e.g. https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call/14220323#14220323) but in the end, it was another question that made me realize the solution, so I updated with a link to that one - thanks! – Philip H Mar 12 '21 at 11:47

1 Answers1

1

First example

can I be sure that url will be defined correctly (i.e. that the second statement will occur after the first)?

Why yes, absolutely. These are just two regular lines of codes, you simply store two strings in two variables; of course they will be executed in order, there's nothing asynchronous here.

Second example

Using Typescript instead of Javascript helped me a lot to understand how async functions work. Here's your example in Typescript :

const syncFunction = ():string => {
    return "hello"
}

const blah = async ():Promise<string> => {
    return syncFunction()
}

(async () => {
    const sayHello:string = await blah();
    console.log(sayHello) // "hello"
})()

As you can see, adding the types helps. An async function always returns a Promise. If you return true, then the returned type isn't boolean, it is Promise<boolean>.

So, return syncFunction() returns a Promise of "hello". Therefore, you must await it to actually get your "hello" string. Then you can log it.

Same code transpiled to JS so it is runnable in a snippet :

const syncFunction = () => {
    return "hello"
}

const blah = async () => {
    return syncFunction()
}

(async () => {
   const sayHello = await blah();
    console.log(sayHello) // "hello"
})()
Jeremy Thille
  • 26,047
  • 12
  • 43
  • 63