0

I often read that async/await is better than .then(). I learned, to use await, I need an async function. To handle errors, I need try/catch. So I built this simple get request:

const isAvailable = async (url) => {
    try {
        const response = await fetch(url);
        const data = await response.json();
        return data;
    } catch (err) {
        console.error(err);
    }
};
const fetchedData = isAvailable("/api");
console.log(fetchedData); // Returns: Promise {status: "pending"}

When I see this, it is somehow logical for me, but I can't really understand it. fetch() returns a Promise, thus fetchedData is a Promise. But the try block shout return an object, thus fetchedData should be a Promise. Even when I see this, it is somehow logical for me, but I can't really understand it, either. fetchedData is a pending Promise and should be awaited as well, so I tried:

const fetchedData = await isAvailable("/api"); //SyntaxError: Unexpected identifier 'isAvailable'. Expected ';' after variable declaration.
console.log(fetchedData); 

I'd say this is because I call await without being in an async function, so I ended with:

isAvailable("/api").then((fetchedData) => {
    console.log(fetchedData);
});

But now I'm back to .then() what I want to avoid in my exercise.

John Doener
  • 119
  • 10
  • The result of an async operation becomes available *sometime later*. `await` enables you to write code that *looks* synchronous, that *looks* like a regular function which returns its result immediately, but of course it doesn't. A value which is only available *sometime later* cannot be available *right now*. Any `async` function will always return a promise, and any caller of an `async` function must always `await` its completion (if its interested in the result). It's async *all the way up*. – deceze Dec 08 '21 at 08:55
  • Every async function (when looked at it from the outside) automatically returns a promise. This promise will resolve to whatever was passed to `return`. Unless you have ES6 modules with top-level await, you will have always a transition between async functions using await to call each other and "regular" functions - and that's the one point where you need to use `then` or `catch` anyway. But in your example, you should probably have a function `async function main ()` that does all this stuff, and only call that function (with `.catch` for good measure, but no `then` since all happens inside.) – CherryDT Dec 08 '21 at 08:58
  • @CherryDt instead if using a `main()` referencing my first code snipped, isn't it the same as just calling `isAvailable()` and putting the url directly in the `fetch()` and logging my `data` instead of returning? Then I'd avoid using then and catch at all. – John Doener Dec 08 '21 at 09:28
  • Yes sure, but I thought you wanted to test how to build such code with `async`/`await`. It does sound fully reasonable to have a separate function `isAvailable` that returns stuff and doesn't log it on its own... (Also, unless you can use ES6 top-level await, you _always_ need one `.catch` because otherwise there is always the chance of an unhandled promise rejection - even with `try`/`catch`, because you may throw another exception inside of the `catch` clause.) – CherryDT Dec 08 '21 at 10:46

0 Answers0