Heim  >  Artikel  >  Web-Frontend  >  Der Unterschied zwischen js asynchronem Rückruf Async/Await und Promise, 6 Gründe, warum Async/Await Promise ersetzt

Der Unterschied zwischen js asynchronem Rückruf Async/Await und Promise, 6 Gründe, warum Async/Await Promise ersetzt

青灯夜游
青灯夜游Original
2018-09-12 16:45:321584Durchsuche

In diesem Kapitel erfahren Sie den Unterschied zwischen Async/Await und Promise im asynchronen js-Rückruf und 6 Gründe, warum Async/Await Promise ersetzt. Es hat einen gewissen Referenzwert. Freunde in Not können sich darauf beziehen. Ich hoffe, es wird Ihnen hilfreich sein.

Was ist Async/Await?

async/await ist eine neue Art, asynchronen Code zu schreiben. Die vorherigen Methoden waren Callback-Funktionen und Promise .

async/await wird basierend auf Promise implementiert und kann nicht für normale Rückruffunktionen verwendet werden.

async/await ist wie Promise nicht blockierend.

async/await lässt asynchronen Code wie synchronen Code aussehen, was seine Magie ist.

Async/Await-Syntax

Im Beispiel gibt die getJSON-Funktion ein Versprechen zurück, das ein JSON-Objekt zurückgibt, wenn das Versprechen erfolgreich aufgelöst wird. Wir rufen einfach diese Funktion auf, drucken das zurückgegebene JSON-Objekt aus und geben „done“ zurück.

Versprechen zu verwenden ist so:

const makeRequest = () =>
  getJSON()
    .then(data => {
      console.log(data)
      return "done"
    })makeRequest()

Async/Await zu verwenden ist so:

const makeRequest = async () => {
  console.log(await getJSON())
  return "done"}makeRequest()

Es gibt einige kleine Unterschiede:

Es gibt mehr Funktionen vor Ein aync-Schlüsselwort. Das Schlüsselwort „await“ kann nur innerhalb von aync definierter Funktionen verwendet werden. Die asynchrone Funktion gibt implizit ein Versprechen zurück, und der Auflösungswert des Versprechens ist der Wert der Funktionsrückgabe. (Der reosolve-Wert im Beispiel ist die Zeichenfolge „done“)

Der erste Punkt impliziert, dass wir „await“ nicht im äußersten Code verwenden können, da es nicht innerhalb der asynchronen Funktion liegt.

// 不能在最外层代码中使用
awaitawait makeRequest()
// 这是会出事情的 
makeRequest().then((result) => {
  // 代码
 })

await getJSON() bedeutet, dass console.log wartet, bis das Versprechen von getJSON erfolgreich gelöst wurde, bevor es ausgeführt wird.

Warum ist Async/Await besser?

1. Einfachheit

Wie aus dem Beispiel ersichtlich ist, spart die Verwendung von Async/Await offensichtlich viel Code. Wir müssen kein .then schreiben, wir müssen keine anonymen Funktionen schreiben, um den Auflösungswert von Promise zu verarbeiten, wir müssen keine redundanten Datenvariablen definieren und wir vermeiden verschachtelten Code. Diese kleinen Vorteile summieren sich schnell, wie in den folgenden Codebeispielen deutlicher wird.

2. Fehlerbehandlung

Async/Await ermöglicht die Behandlung von synchronen und asynchronen Fehlern durch Try/Catch. Im folgenden Promise-Beispiel kann try/catch den JSON.parse-Fehler nicht verarbeiten, da er innerhalb des Promise liegt. Wir müssen .catch verwenden, damit der Fehlerbehandlungscode sehr redundant ist. Darüber hinaus wird unser eigentlicher Produktionscode komplizierter sein.

const makeRequest = () => {
  try {
    getJSON()
      .then(result => {
        // JSON.parse可能会出错
        const data = JSON.parse(result)
        console.log(data)
      })
      // 取消注释,处理异步代码的错误
      // .catch((err) => {
      //   console.log(err)
      // })
  } catch (err) {
    console.log(err)
  }}

Wenn Sie aync/await verwenden, kann Catch JSON.parse-Fehler verarbeiten:

const makeRequest = async () => {
  try {
    // this parse may fail
    const data = JSON.parse(await getJSON())
    console.log(data)
  } catch (err) {
    console.log(err)
  }}

3. Bedingte Anweisung

Im folgenden Beispiel müssen Sie die Daten abrufen und geben Sie dann die Daten entsprechend zurück. Entscheiden Sie, ob Sie direkt zurückkehren oder weiterhin weitere Daten abrufen möchten. ·

const makeRequest = () => {
  return getJSON()
    .then(data => {
      if (data.needsAnotherRequest) {
        return makeAnotherRequest(data)
          .then(moreData => {
            console.log(moreData)
            return moreData          })
      } else {
        console.log(data)
        return data      }
    })}

Diese Codes bereiten mir schon beim Anblick Kopfschmerzen. Es kann leicht zu Verwechslungen mit Verschachtelungen (6 Ebenen), Klammern und Rückgabeanweisungen kommen, die nur das Endergebnis an das äußerste Versprechen übergeben müssen.

Der obige Code wurde mit async/await geschrieben, was die Lesbarkeit erheblich verbessern kann:

const makeRequest = async () => {
  const data = await getJSON()
  if (data.needsAnotherRequest) {
    const moreData = await makeAnotherRequest(data);
    console.log(moreData)
    return moreData  } else {
    console.log(data)
    return data    
  }}

Zwischenwert

Sie sind wahrscheinlich auf ein solches Szenario gestoßen, das Promise1 aufruft, Verwenden Sie das von Promise1 zurückgegebene Ergebnis, um Promise2 aufzurufen, und verwenden Sie dann die Ergebnisse beider, um Promise3 aufzurufen. Ihr Code sieht wahrscheinlich so aus:

const makeRequest = () => {
  return promise1()
    .then(value1 => {
      return promise2(value1)
        .then(value2 => {        
          return promise3(value1, value2)
        })
    })}

Wenn Promise3 keinen Wert1 erfordert, können Sie die Promises einfach flach verschachteln. Wenn Sie eine Verschachtelung nicht ertragen können, können Sie die Werte 1 und 2 in Promise.all einfügen, um eine tiefe Verschachtelung zu vermeiden:

const makeRequest = () => {
  return promise1()
    .then(value1 => {
      return Promise.all([value1, promise2(value1)])
    })
    .then(([value1, value2]) => {      
      return promise3(value1, value2)
    })}

Dieser Ansatz opfert die Semantik zugunsten der Lesbarkeit. Es gibt keinen anderen Grund, Wert1 und Wert2 in ein Array einzufügen, als eine Verschachtelung zu vermeiden.

Wenn Sie async/await verwenden, wird der Code extrem einfach und intuitiv.

const makeRequest = async () => {
  const value1 = await promise1()
  const value2 = await promise2(value1)
  return promise3(value1, value2)}

5. Fehlerstapel

Im folgenden Beispiel werden mehrere Versprechen aufgerufen. Angenommen, irgendwo in der Versprechenskette wird ein Fehler ausgegeben:

const makeRequest = () => {
  return callAPromise()
    .then(() => callAPromise())
    .then(() => callAPromise())
    .then(() => callAPromise())
    .then(() => callAPromise())
    .then(() => {
      throw new Error("oops");
    })}makeRequest()
  .catch(err => {
    console.log(err);
    // output
    // Error: oops at callAPromise.then.then.then.then.then (index.js:8:13)
  })

Rückkehr von der Versprechenskette Der Fehlerstapel gibt keinen Hinweis darauf, wo der Fehler aufgetreten ist. Schlimmer noch, es ist irreführend; die einzige Funktion im Fehlerstapel heißt callAPromise, was nichts mit dem Fehler zu tun hat. (Der Dateiname und die Zeilennummer sind weiterhin nützlich).

Allerdings zeigt der Fehlerstapel in async/await auf die Funktion, in der sich der Fehler befindet:

const makeRequest = async () => {
  await callAPromise()
  await callAPromise()
  await callAPromise()
  await callAPromise()
  await callAPromise()
  throw new Error("oops");}makeRequest()
  .catch(err => {
    console.log(err);
    // output
    // Error: oops at makeRequest (index.js:7:9)
  })

In einer Entwicklungsumgebung ist dieser Vorteil nicht groß. Es ist jedoch sehr nützlich, wenn Sie das Fehlerprotokoll der Produktionsumgebung analysieren. Zu diesem Zeitpunkt ist es besser zu wissen, dass der Fehler in makeRequest aufgetreten ist, als zu wissen, dass der Fehler in der Then-Kette aufgetreten ist.

6. Debuggen

Der letzte und sehr wichtige Punkt ist, dass async/await das Code-Debuggen erleichtern kann. 2 Gründe, warum das Debuggen von Promises mühsam ist:

1) Sie können keine Haltepunkte in Pfeilfunktionen setzen, die Ausdrücke zurückgeben

Der Unterschied zwischen js asynchronem Rückruf Async/Await und Promise, 6 Gründe, warum Async/Await Promise ersetzt

2) Wenn Sie einen Haltepunkt setzen den .then-Codeblock und verwenden Sie die Tastenkombination „Step Over“. Der Debugger springt nicht zum nächsten .then, da er nur den asynchronen Code überspringt.

Bei Verwendung von „await/async“ benötigen Sie nicht mehr so ​​viele Pfeilfunktionen, sodass Sie „await“-Anweisungen überspringen können, genau wie beim Debuggen von synchronem Code

Der Unterschied zwischen js asynchronem Rückruf Async/Await und Promise, 6 Gründe, warum Async/Await Promise ersetzt

Fazit

Async/Await ist eine der revolutionärsten Funktionen, die in den letzten Jahren zu JavaScript hinzugefügt wurden. Es wird Ihnen klar machen, wie schlecht die Promise-Syntax ist, und Ihnen eine intuitive Alternative bieten.

Sorge

Vielleicht haben Sie berechtigte Zweifel an Async/Await:
Dadurch wird asynchroner Code weniger offensichtlich: Wir sind es gewohnt, Callback-Funktionen oder .then zu verwenden, um asynchronen Code zu identifizieren, und es kann mehrere Wochen dauern, bis wir uns an das neue Flag gewöhnt haben. C# verfügt jedoch schon seit vielen Jahren über diese Funktion, und Freunde, die damit vertraut sind, sollten wissen, dass sich die vorübergehende Unannehmlichkeit lohnt.
Node 7 ist kein LTS (Long-Term-Support-Release): Node 8 wird jedoch nächsten Monat veröffentlicht und die Migration Ihres Codes auf die neue Version wird sehr einfach sein.

Das obige ist der detaillierte Inhalt vonDer Unterschied zwischen js asynchronem Rückruf Async/Await und Promise, 6 Gründe, warum Async/Await Promise ersetzt. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn