async

Warum async/await rockt

Von am 19.05.2018

In diesem Beitrag werden wir uns ein cooles Feature des ECMAScript 2017 Standards anschauen. Nun ist es möglich so genannte asynchrone Funktionen zu verwenden.

Eine asynchrone Funktion lässt sich ganz einfach über das „async“ Keyword deklarieren. Damit wird der Funktion impliziert, dass diese als Rückgabewert immer einen Promise liefert.

 

async function foo () {
  return 'value'
}

const result = foo() // Promise

foo().then((result) => result ) // 'value'

An dieser Stelle ein kleiner Exkurs zu Promises:

Ein Promise ist eine Art Platzhalter Objekt für ein zukünftiges Ergebnis. Das Ergebnis kann nun nach einer bestimmten Zeit erfolgreich eintreffen (fulfilled) oder ein Fehler auftreten (rejected).

Diese beiden Fälle lassen sich beispielweise durch das chainen eines „.then((result) => {})“ Handlers bzw. „.catch((error) => {})“ weiter verarbeiten.

Vor allem bei komplexeren/verschachtelten Codeflüssen sind Promises nicht immer optimal.

async/await rockt an dieser Stelle doch um einiges mehr 🙂 Denn damit lässt sich asynchroner Code fast wie synchroner Code schreiben. In async functions kann man nun das await Keyword verwenden. Wie der Worlaut vermuten lässt, kann man mit await das Ergebnis eines Promises abwarten. Dazu nun einige Codebeispiele.

 

//Promise style
fetchUserInfo()
  .then(user => {
    //do something with the user
    })

  .catch(e => {
    console.log(e)
  })

//async/await style
try{
  const result = await fetchUserInfo()
} catch(e) {
  console.log(e)
}

 

Anstelle von then und catch können wir try/catch verwenden und das Promise Result einfach awaiten. In diesem Beispiel mag der Unterschied vielleicht noch nicht sonderlich groß sein. Schauen wir uns deshalb das nächste Beispiel an:

 

// Promise style
fetchUserInfo()
  .then(user => {
    return getLocationForUser(user)
      .then((info) => {
        user.info = info
        return user
      })
  })
  .catch(e => {
    console.log(e)
  })

// async/await style
try{
  const result = await fetchUserInfo()
  const info = await getLocationForUser(user)
  result.info = info
} catch(e) {
  console.log(e)
}

 

Wir sehen, dass wir mit await sehr leicht im gleichen Scope bleiben können und uns dadurch tiefes Verschachteln ersparen können.

Bei parallelen Promises wird async/await in Kombination mit Destructuring noch viel knackiger 🙂

 

// Promise style
function foo() {
  return Promise .all([
    fetchUserInfo(),
    fetchLocation()])
    .then(([cities, countries]) => {
      return { cities, countries }
    })
}

// async/await style
async function foo() {
  await [cities, countries] = Promise.all([
    fetchCities(),
    fetchCountries()
  ])

  return { cities, countries }
}

 

async/await hilft uns Codestrukturen leichter folgen zu können und sauberen Code zu schreiben.
Den einzige Nachteil den die schlankeren Syntax birgt ist das leichter Vergessen des await Keywords was oft zu interessanten Ergebnissen führt 🙂

The comments are closed.