0

I just try to understand what is happening - why my async method is waiting for another async method only if the response is deconstructed?

So I have some example code:

Dummy promise

const psedoRequest = () => {
  return new Promise(resolve => setTimeout(resolve, 2000, "resolved"));
}

Dummy method which is calling promise

const methodRequest = async() => {
  let response = "";
  let error = "";

  try {
    response = await psedoRequest();
  } catch (e) {
    error = e;
  }

  return { response, error };
}

Actual methods

const invalidMainMethod = async() => {

  const results = await methodRequest().response;
  console.log('Invalid', results)
  // the same would be with:
  // const response = await methodRequest().response; 
  // console.log('Invalid', response );
}

const validMainMethod = async() => {
  let results = ""

  const { response } = await methodRequest();
  results = response;
  console.log('Valid', results);
}

Console log returns:

Invalid undefined
Valid resolved

Why deconstructing actually works in that case - so it's waiting for a response while accessing directly .response is not? I thought that deconstructing is some syntactic sugar.

Marian Klösler
  • 620
  • 8
  • 22
  • 3
    because `await methodRequest().response` is equivalent to `await (methodRequest().response)` but you would actually need `(await methodRequest()).response` – derpirscher Jan 26 '23 at 14:50

3 Answers3

3
const results = await methodRequest().response;

Property accessing has higher precedence than await so this:

  1. Calls methodRequest
  2. Gets a promise object
  3. Reads response (which is undefined) from the promise
  4. awaits undefined (which isn't a promise so has no significant effect)
  5. Assigns undefined to results

Later the promise resolves.

You could get the desired effect by using parentheses to override precedence:

const results = (await methodRequest()).response;

const { response } = await methodRequest();

await has higher precedence than = so it awaits the promise first then assigns and deconstruction is done as part of assignment.

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

This is ambiguous (to humans) and doesn't mean what you think it means:

await methodRequest().response

Are you awaiting methodRequest()? Or are you awaiting the response property from what methodRequest() returns?

Be explicit:

const results = (await methodRequest()).response;
David
  • 208,112
  • 36
  • 198
  • 279
1

I see David was faster, but since I have already written my response here it is anyways:

The simple difference here is the syntax:

const response = await methodRequest().response;

This snippet awaits methodRequest().response What you are expecting it to do is to await methodRequest() and then get the response.

const { response } = await methodRequest();

This awaits methodRequest() and then takes the response from it like this:

const response = (await methodRequest()).response
Juhuja
  • 147
  • 5