4

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?

3
  • if it was c# i'd expect the 2nd version but in javascript 'then' seems to be much more popular than the equivilant .ContinueWith
    – Ewan
    Sep 15, 2018 at 9:16
  • ..although, do you need the second await?
    – Ewan
    Sep 15, 2018 at 9:17
  • is the purpose of async/await to stop using promises completely? -- No, async functions return promises. See javascript.info/async-await Sep 15, 2018 at 16:35

2 Answers 2

2

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.
1

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.

2
  • 1
    Couldn’t you use just let t1 = loadMyProfileData(userId); let t2 = loadOrders(userId); this.profileData = await t1; this.orders = await t2;? This variant seems to be simpler than Promise.all.
    – Vlad
    Sep 16, 2018 at 5:49
  • @Vlad, yes, you can do that too. I don't believe it's simpler (or more complex either), I believe it's a matter of personal preference. With your approach, while being correct, you're relying that the promises will execute in parallel and there's also the overhead of having to setup them before. I feel like the parallel execution intent is not completely clear from your code. My demonstration, while not perfect, contains this intent of parallel execution (however it's not idea either). The optimal solution would probably be memoizing the promises and awaiting those.
    – Andy
    Sep 16, 2018 at 7:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.