-2

We're trying to get the response JSON from a GET request.

When we print result from inside the get function, the JSON gets printed out like you expect.

However, when we return it and then try to print it, we get a Promise stuck on <pending>.

Below is our code:

"use strict";

async function get(url) {
    let response = await fetch(url);

    if (!response.ok) {
        throw new Error(`An error occured: ${response.status} ${response.statusText}`);
    }

    let result = await response.json();

    console.log("result inside function", result);
    return result;
}

let url = "OUR_URL";
let result = get(url);
console.log("result outside function: ", result);

Below is the output:

result outside function:  Promise {<pending>}
result inside function {success: true, statusCode: 200}

Based on the order of the output statements above, the outer code is executing first before the code inside the function gets resolved despite having await inside the function. Unfortunately, the outside code isn't in an async function, so it can't use await.

However, when we use then() outside the function, we are able to get the response just fine:

get(url).then(result => {
    console.log("result outside function, inside then: ", result);
});

Below is the output:

result inside function {success: true, statusCode: 200}
result outside function, inside then:  {success: true, statusCode: 200}

Above, the order of the output statements is as expected, with the inside one executing first before the ouside one.

We have seen this answer, but it hasn't clicked for us on JavaScript.

We have three questions:

  1. What is JavaScript doing here, exactly?

  2. Is there a way to get the response outside the function without having to use then()?

    2.1. If the answer to the above is no, is there a way to get the response from inside .then() and expose it outside?

Floating Sunfish
  • 4,920
  • 5
  • 29
  • 48
  • 1
    you have to `await` your call to `get` – Daniel A. White Feb 17 '21 at 03:03
  • 1
    You need to understand blocking / non blocking code along with execution stack.. using async on a function above in the code does not automatically make the code below wait for it to finish.. the async code is simply referenced and pushed aside while it does its work and js continues and moves on to the next line of code.. – Nishant S Vispute Feb 17 '21 at 03:11
  • @Evert Ah, yes. We noted in the OP that we have seen that answer, but it hasn't quite clicked for us in JavaScript when we posted the question. Thanks for bringing it up though! – Floating Sunfish Feb 17 '21 at 03:13

1 Answers1

2

You need to await the get function. Also, side note, use const if you're not reassigning the variable.

async function get(url) {
    const response = await fetch(url);

    if (!response.ok) {
        throw new Error(`An error occured: ${response.status} ${response.statusText}`);
    }

    const result = await response.json();

    console.log("result inside function", result);
    return result;
}

(async () => {
  const url = "OUR_URL";
  const result = await get(URL);
  console.log("result outside function: ", result);
})();
selfagency
  • 1,481
  • 1
  • 9
  • 12
  • I see, but wrapping the outside call with `async` seems to be the same as using `then()` in that the result will only be accessible within said wrapping. Is there no way to expose the result to outside, non-async/then code? – Floating Sunfish Feb 17 '21 at 03:10
  • 1
    Unfortunately not at the moment, but [top-level await](https://github.com/tc39/proposal-top-level-await) is a stage 3 candidate for inclusion in the JavaScript specification. – selfagency Feb 17 '21 at 03:18
  • Ah, I hope that gets implemented someday then! – Floating Sunfish Feb 17 '21 at 03:20