Async function is only available in ES8

class Products {
    async getProducts() {
        try {
            const result = await fetch("products.json");
            return result;
        } catch (error) {
            console.log(error);
        }
    }
}

What exactly is your question? You only provided some code without any context of what you are trying to do or what is wrong.

If you are using some framework or library, you will have babel, so who cares where is available async await ?

I think fetch is already an async function. So there is no need of await in front of fetch
if i am wrong just correct me.

if You want to fetch something from api

fetch(`http:\\server domain`)
.then((res)=>{
return res.,json()
}).then((res)=>{
return res
// this is only for fetching json data from api
//
}

Just correct me if i am wrong

You are right but there’s no need for the 2nd .then call since you’re just returning the same thing unless you wanted to specify some other transformation I’m not aware of.

And the async keyword in getProducts is indeed pointless, it does not need to be there because a call to fetch (even with .thens) is already an async promise. I’d just do:

class Products {
  getProducts() {
    return fetch('products.json').then(r => r.json())
  }
}

Which to anyone familiar with angular is almost the same as a Service function that returns an Observable, or in this case, a promise.

.then() and await are both different ways to consume a promise. You could use either but await has a cleaner syntax so I would recommend using it instead. The second .then is for the .json call which also returns a promise

I think the best way to define it is as follows:

  • .then: Is an alias for an operation called “flatMap” famous in functional programming languages that support monadic data structures and procedures. Sounds too fancy but all it does is: transforms whatever is in the container (in this case, a Promise; in other languages: a Future) with whatever the callback you pass to it returns and then wraps said value in the same container. Why flatMap and not just a regular map? Because .then transforms a promise of a promise into a single promise, hence the flat in flatMap.
Promise.resolve(25).then(Math.sqrt) // this maps the inner 25 to a 5 but keeps the Promise wrapper. So when the next .then comes into play, it'll now receive a 5.

fetch('https://someapi.com/')
  .then(r.json())
  .then({ someProp } => fetch('https://anotherapi.com/' + someProp))
  .then(console.log)
// The above code evaluates to a Promise(undefined)
// because console.log is a void function that returns undefined.
// But it doesn't matter because you already did some side effect
// with the value of the intermediate Pormise(Object) returned
// from 'anotherapi.com'. Notice how it's not a
// Promise(Promise(Object) because of the
// pseudo-monadic nature of promises in JS.

Why can we consume the result? Because JS is not a purely functional language and it allows side effects, so you can pretty much do anything with it like assigning it to an external variable or global state, log it, send it inside a POST request somewhere, save it to localstorage, etc.

  • Async/Await: Works just the same except it expects whatever the promise resolves to. A return value from an async function is a Promise wrapping the return value. All the side effects are performed inside the entire async function and then return (or not) whatever you want to return. Async functions can be void or Promise(something) it only matters to the problem you’re trying to solve.

Fetch returns a Promise of Response (a special type of object), a call to .json() part of the Response prototype (or .text()) returns a Promise of a JSON object or a String if you called .text(). That’s why I said there’s no point in doing a .then that all it does is return whatever it’s passed to it, that’s called an “identity function” f(x) = x useful for some things but not in this case.

async function foo() { return 5 } yields Promise(5) when called. So you can basically call it from another async function with an await and you’ll get the pure 5.

2 Likes

What will happen with your code if backend sends you text/plain or html ?

Javascript doesn’t know how to interpret HTML or XML (as far as I know) by itself without the help of libraries, only JSON.

The response object has a method called .text() which transforms the ReadableStream into a string.

Now, if it’s HTML or XML you can use the string or if you want to structure it somehow, use a library like Cheerio or any other.

asda

Async function is ES8. Fetch is what ES6? Does that imply a progression?
We use the ‘async’ and ‘await’ in C#.NET code for asynchronous. I have to
say that the chained ‘then()’ operations add more confusion due to the dependence
of their positioning whereas the Async function of ES8 is simpler to understand and
with the keywords also more self documenting as to their purpose.

You can use callbacks or promises for asynchronous code in JS. The then syntax is promises. They’re equivalent to futures in C# (Task<T>). The async/await syntax in JS is just syntactic sugar over promises, and is taken from C#.

There’s no such thing as ES8, and ES6 was a temporary name. The language gets features added via the review process handled by the tc39 group. It was initially yearly additions to the language (so ES2015, ES2016, etc), now it is just when proposals reach stage 4 of the review process & have been implemented across browsers.

babel still makes the year distinctions, because by its nature it has to. Far as I know, ES2019 is basically “whatever made it to stage 4 in 2018”. It even has abbreviations up to ES9 (possibly more?) but those are confusing to almost everyone.

Yeah I should have added that (the env preset takes most up the date plugins I think though if set to do so? I tend to try to ignore the config setup until something stops working)