Question

I've written a bit of code that looks like this:

async function fetchData() {
    const json = await fetch(ENDPOINT + key.key).then(data => data.json());
    //Do something with the data
}

It's pretty clear and straight forward what I'm doing here.

I'm just wondering if it's normal to combine both the older Promise style, and the new async/await style like this.

If I wasn't to use .then then I'd be something like this:

async function fetchData() {
    const data = await fetch(ENDPOINT + key.key); 
    const json = await data.json(); 
    //do something with the data
}

Unless I'm missing something here? I guess the question is - is the purpose of async/await to stop using promises completely - or what?

Was it helpful?

Solution

Async await is promises under the hood. So, you can get away with async await most of the time when you have a sequence of dependent async steps to perform.

However, there are times when you want to run a set of operations in series or parallel. There you'll definitely need Promise.all or await in a for loop.

Regarding your code:

  1. You need not await on the return statement of an async function, you can simply return the promise directly.
  2. Keeping a promise in a variable is only needed when you want to do something other than await on it.

OTHER TIPS

Even in modern application development promises are very useful and you generally do not want to await everything. Why? Because awaiting something is blocking.

Imagine a scenario, where you would have an application and upon opening a screen you would need to call two unrelated REST endpoints.

function loadMyProfileData(userId) { ... }
function loadOrders(userId) { ... }

Both of those functions would do an HTTP REST request and return a promise. If you had the following function:

async function onScreenLoad(userId) {
    this.profileData = await loadMyProfileData(userId);
    this.orders      = await loadOrders(userId);
}

you would only start loading the orders once your profile data is fetched, even though the orders function clearly does not depend on the result of profile data at all.

In such scenario you would most likely want to be looking for something like this:

async function onScreenLoad(userId) {
    let [profileData, orders] =
        await Promise.all([loadMyProfileData(userId), loadOrders(userId)]);

    this.profileData = profileData;
    this.orders      = orders;
}

That way you load the data at the same time.

async/await is an amazing syntax sugar but is not to be taken for granted and used without knowing it's side effects.

Licensed under: CC-BY-SA with attribution
scroll top