JS async

#jedenasta37 Dzisiaj będzie o największej nowości ES8, czyli o funkcjach asynchronicznych. Jest to artykuł dla ciut bardziej zaawansowanych programistów JavaScript, potrzebujesz ogólnie mieć pojęcie czym jest callback, oraz promise.
JavaScript jest językiem jednowątkowym (nie mówimy o web workerach, bo to inna historia). Wiemy jednak, że jest w stanie bardzo efektywnie obsłużyć rzeczy, które dzieją się asynchronicznie (zapytania po rest API, timeout, kliknięcia na stronie). Dzieje się tak dzięki event loop. Która działa w silniku odpowiedzialnym za JS.
Żeby obsłużyć zdarzenie asynchroniczne mieliśmy do tej pory 2 możliwości:

  • callback, czyli funkcja zwrotna wywoływana po zdarzeniu; wadą tego rozwiązania jest tzw callback hell, czyli kilkukrotne zagnieżdżenie wewnątrz siebie obsług różnych zdarzeń, czyli bałagan w kodzie jaki generują. Przykład:
    fs.readdir(source, function (err, files) {
      if (err) {
        console.log('Error finding files: ' + err)
      } else {
        files.forEach(function (filename, fileIndex) {
          console.log(filename)
          gm(source + filename).size(function (err, values) {
            if (err) {
              console.log('Error identifying file size: ' + err)
            } else {
              console.log(filename + ' : ' + values)
              aspect = (values.width / values.height)
              widths.forEach(function (width, widthIndex) {
                height = Math.round(width / aspect)
                console.log('resizing ' + filename + 'to ' + height + 'x' + height)
                this.resize(width, height).write(dest + 'w' + width + '_' + filename, function(err) {
                  if (err) console.log('Error writing file: ' + err)
                })
              }.bind(this))
            }
          })
        })
      }
    })

    Żeby pozbyć się tego wielopiętrowca z kodu, się pojawił się mechanizm promise.

  • promise mechanizm pod którym siedzą callbacki, natomiast:
    • można łańcuchować promise
    • dzięki Promise.all można agregować kilka promisów, po czym obsłużyć jak już się wszystkie zakończą.
      https://codepen.io/d01odekx/pen/oEKPgX?editors=00

Promise są ok, natomiast powodują kolejne zagnieżdżenia w ciałach funkcji. Dlatego pojawiła się koncepcja funkcji async która wygląda ja normalna funkcja, tylko że zwraca promise, oraz czeka  na wykonanie, gdy napotka słowo kluczowe await. Co ciekawe za słowem await może być synchroniczna dana, wtedy kod wykona się jak normalna funkcja. Przykład:

async & promise dla danych asynchronicznych:

Funkcja asynchroniczna, gdy np serwer zwróci błąd rzuca wyjątek tak jak tutaj:

Najfajniejszą rzeczą związaną z funkcjami asynchronicznymi jest to, że możemy je łączyć z promise’ami, co daje nam możliwość zrobienia agregatu Promise.all, a następnie obsłużenia go funkcją asynchroniczną tak jak tutaj:

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *