Heim Web-Frontend js-Tutorial Async- und Await-Funktionsanalyse in Node.js

Async- und Await-Funktionsanalyse in Node.js

Feb 24, 2018 am 09:10 AM
await javascript node.js

Dieser Artikel führt Sie hauptsächlich in die relevanten Kenntnisse der Async- und Await-Funktionen in Node.js ein. Sie erfahren, wie Sie die Async-Funktion (async/await) in Node.js verwenden, um Callback oder Promise zu vereinfachen Referenz Als Referenzwert können Freunde, die es benötigen, darauf verweisen. Ich hoffe, es kann jedem helfen.

Asynchrone Sprachstrukturen gibt es bereits in anderen Sprachen, wie z. B. async/await von c#, den Coroutinen von Kotlin und den Goroutinen von go. Mit der Veröffentlichung von Node.js 8 ist auch die lang erwartete async-Funktion implementiert Standard.

Was ist die asynchrone Funktion in Node?

Wenn eine Funktion als Async-Funktion deklariert wird, gibt sie ein AsyncFunction-Objekt zurück. Sie ähneln Generatoren darin, dass die Ausführung angehalten werden kann. Der einzige Unterschied besteht darin, dass sie ein Promise anstelle eines { value: any, done: Boolean }-Objekts zurückgeben. Sie sind sich jedoch immer noch sehr ähnlich und Sie können das Co-Paket verwenden, um die gleiche Funktionalität zu erhalten.

In einer asynchronen Funktion können Sie warten, bis das Versprechen abgeschlossen ist, oder den Grund für seine Ablehnung erfassen.

Wenn Sie einen Teil Ihrer eigenen Logik in Promise implementieren möchten

function handler (req, res) {
 return request('https://user-handler-service')
 .catch((err) => {
  logger.error('Http error', err)
  error.logged = true
  throw err
 })
 .then((response) => Mongo.findOne({ user: response.body.user }))
 .catch((err) => {
  !error.logged && logger.error('Mongo error', err)
  error.logged = true
  throw err
 })
 .then((document) => executeLogic(req, res, document))
 .catch((err) => {
  !error.logged && console.error(err)
  res.status(500).send()
 })
}
Nach dem Login kopieren

Sie können async/await verwenden, um diesen Code wie synchron ausgeführten Code aussehen zu lassen

async function handler (req, res) {
 let response
 try {
 response = await request('https://user-handler-service') 
 } catch (err) {
 logger.error('Http error', err)
 return res.status(500).send()
 }
 let document
 try {
 document = await Mongo.findOne({ user: response.body.user })
 } catch (err) {
 logger.error('Mongo error', err)
 return res.status(500).send()
 }
 executeLogic(document, req, res)
}
Nach dem Login kopieren

In der alten v8-Version erhalten Sie eine Warnung, wenn eine Versprechenablehnung vorliegt, die nicht behandelt wird, und Sie müssen keine Funktion zum Abhören von Ablehnungsfehlern erstellen. Es wird jedoch empfohlen, in diesem Fall Ihre Bewerbung zu beenden. Denn wenn Sie Fehler nicht behandeln, befindet sich die Anwendung in einem unbekannten Zustand.

process.on('unhandledRejection', (err) => { 
 console.error(err)
 process.exit(1)
})
Nach dem Login kopieren

asynchrones Funktionsmuster

Beim Umgang mit asynchronen Vorgängen gibt es viele Beispiele dafür, dass sie wie synchroner Code aussehen. Wenn Sie Promise oder Rückrufe verwenden, um das Problem zu lösen, müssen Sie ein sehr komplexes Muster oder eine externe Bibliothek verwenden.

Es ist eine sehr komplizierte Situation, wenn Sie die asynchrone Erfassung von Daten in einer Schleife verwenden oder if-else-Bedingungen verwenden müssen.

Exponentieller Rollback-Mechanismus

Die Verwendung von Promise zur Implementierung der Rollback-Logik ist ziemlich umständlich.

function requestWithRetry (url, retryCount) {
 if (retryCount) {
 return new Promise((resolve, reject) => {
  const timeout = Math.pow(2, retryCount)
  setTimeout(() => {
  console.log('Waiting', timeout, 'ms')
  _requestWithRetry(url, retryCount)
   .then(resolve)
   .catch(reject)
  }, timeout)
 })
 } else {
 return _requestWithRetry(url, 0)
 }
}
function _requestWithRetry (url, retryCount) {
 return request(url, retryCount)
 .catch((err) => {
  if (err.statusCode && err.statusCode >= 500) {
  console.log('Retrying', err.message, retryCount)
  return requestWithRetry(url, ++retryCount)
  }
  throw err
 })
}
requestWithRetry('http://localhost:3000')
 .then((res) => {
 console.log(res)
 })
 .catch(err => {
 console.error(err)
 })
Nach dem Login kopieren

Der Code ist sehr mühsam anzusehen, und Sie möchten ihn nicht sehen solcher Code. Wir können dieses Beispiel mit async/await wiederholen, um es einfacher zu machen

function wait (timeout) {
 return new Promise((resolve) => {
 setTimeout(() => {
  resolve()
 }, timeout)
 })
}

async function requestWithRetry (url) {
 const MAX_RETRIES = 10
 for (let i = 0; i <= MAX_RETRIES; i++) {
 try {
  return await request(url)
 } catch (err) {
  const timeout = Math.pow(2, i)
  console.log(&#39;Waiting&#39;, timeout, &#39;ms&#39;)
  await wait(timeout)
  console.log(&#39;Retrying&#39;, err.message, i)
 }
 }
}
Nach dem Login kopieren

Der obige Code sieht sehr komfortabel aus, nicht wahr

Zwischenwert

Nicht wie das vorherige Beispiel Also Beängstigend, wenn Sie eine Situation haben, in der drei asynchrone Funktionen abwechselnd voneinander abhängen, müssen Sie aus mehreren hässlichen Lösungen wählen.

FunktionA gibt ein Versprechen zurück, dann benötigt FunktionB diesen Wert und FunktionC benötigt die Werte, nachdem FunktionA und FunktionB abgeschlossen sind.

Option 1: dann Weihnachtsbaum

function executeAsyncTask () {
 return functionA()
 .then((valueA) => {
  return functionB(valueA)
  .then((valueB) => {   
   return functionC(valueA, valueB)
  })
 })
}
Nach dem Login kopieren

Mit dieser Lösung können wir WertA und WertB im dritten Then erhalten, und dann können wir WertA und WertB wie die beiden vorherigen Then-Werte erhalten . Sie können den Weihnachtsbaum hier nicht platt machen (die Hölle ruinieren), sonst verlieren Sie den Abschluss und valueA ist in functioinC nicht verfügbar.

Option 2: Wechseln Sie zum Bereich der oberen Ebene

function executeAsyncTask () {
 let valueA
 return functionA()
 .then((v) => {
  valueA = v
  return functionB(valueA)
 })
 .then((valueB) => {
  return functionC(valueA, valueB)
 })
}
Nach dem Login kopieren

In diesem Weihnachtsbaum verwenden wir den höheren Bereichs-Retainer-WertA, da der Bereich von valueA in allen Bereichen außerhalb des Bereichs liegt FunktionC kann den Wert der ersten abgeschlossenen FunktionA abrufen.

Dies ist eine sehr „richtige“ Syntax zum Reduzieren der .then-Kette. Auf diese Weise müssen wir jedoch zwei Variablen valueA und v verwenden, um denselben Wert zu halten.

Option 3: Verwenden Sie ein zusätzliches Array

function executeAsyncTask () {
 return functionA()
 .then(valueA => {
  return Promise.all([valueA, functionB(valueA)])
 })
 .then(([valueA, valueB]) => {
  return functionC(valueA, valueB)
 })
}
Nach dem Login kopieren

Verwenden Sie ein Array von functionA, um valueA und Promise zusammen zurückzugeben, was den Weihnachtsbaum effektiv platt machen kann (Callback-Hölle).

Option 4: Schreiben Sie eine Hilfsfunktion

const converge = (...promises) => (...args) => {
 let [head, ...tail] = promises
 if (tail.length) {
 return head(...args)
  .then((value) => converge(...tail)(...args.concat([value])))
 } else {
 return head(...args)
 }
}
functionA(2)
 .then((valueA) => converge(functionB, functionC)(valueA))
Nach dem Login kopieren

Dies ist machbar. Schreiben Sie eine Hilfsfunktion, um die Kontextvariablendeklaration abzuschirmen. Aber ein solcher Code ist sehr schwer zu lesen, insbesondere für Leute, die mit dieser Magie nicht vertraut sind.

Mit async/await verschwanden unsere Probleme auf magische Weise.

async function executeAsyncTask () {
 const valueA = await functionA()
 const valueB = await functionB(valueA)
 return function3(valueA, valueB)
}
Nach dem Login kopieren

Mit async/await mehrere parallele Anfragen bearbeiten

Es ist fast das Gleiche wie oben, wenn Sie so wollen Um dies gleichzeitig zu tun, können Sie mit async/await ganz einfach mehrere asynchrone Aufgaben ausführen und deren Werte dann an verschiedenen Stellen verwenden.

async function executeParallelAsyncTasks () {
 const [ valueA, valueB, valueC ] = await Promise.all([ functionA(), functionB(), functionC() ])
 doSomethingWith(valueA)
 doSomethingElseWith(valueB)
 doAnotherThingWith(valueC)
}
Nach dem Login kopieren

Array-Iterationsmethode

Sie können asynchrone Funktionen in Zuordnungs-, Filter- und Reduzierungsmethoden verwenden. Obwohl diese möglicherweise nicht sehr intuitiv erscheinen, können Sie mit dem folgenden Code in der Konsole experimentieren .

1.map

function asyncThing (value) {
 return new Promise((resolve, reject) => {
 setTimeout(() => resolve(value), 100)
 })
}

async function main () {
 return [1,2,3,4].map(async (value) => {
 const v = await asyncThing(value)
 return v * 2
 })
}

main()
 .then(v => console.log(v))
 .catch(err => console.error(err))
Nach dem Login kopieren

2.filter

function asyncThing (value) {
 return new Promise((resolve, reject) => {
 setTimeout(() => resolve(value), 100)
 })
}
async function main () {
 return [1,2,3,4].filter(async (value) => {
 const v = await asyncThing(value)
 return v % 2 === 0
 })
}
main()
 .then(v => console.log(v))
 .catch(err => console.error(err))
Nach dem Login kopieren

3.reduce

function asyncThing (value) {
 return new Promise((resolve, reject) => {
 setTimeout(() => resolve(value), 100)
 })
}
async function main () {
 return [1,2,3,4].reduce(async (acc, value) => {
 return await acc + await asyncThing(value)
 }, Promise.resolve(0))
}
main()
 .then(v => console.log(v))
 .catch(err => console.error(err))
Nach dem Login kopieren

Lösung:

[ Promise { <pending> }, Promise { <pending> }, Promise { <pending> }, Promise { <pending> } ]
[ 1, 2, 3, 4 ]
10
Nach dem Login kopieren

Wenn es sich um Karteniterationsdaten handelt, sehen Sie, dass der Rückgabewert [2, 4, 6, 8] ist. Das einzige Problem besteht darin, dass jeder Wert von der AsyncFunction-Funktion in ein Versprechen eingeschlossen wird

Wenn Sie also ihre Werte erhalten möchten, müssen Sie das Array an Promise.All() übergeben, um das Promise zu entpacken.

main()
 .then(v => Promise.all(v))
 .then(v => console.log(v))
 .catch(err => console.error(err))
一开始你会等待 Promise 解决,然后使用map遍历每个值
function main () {
 return Promise.all([1,2,3,4].map((value) => asyncThing(value)))
}
main()
 .then(values => values.map((value) => value * 2))
 .then(v => console.log(v))
 .catch(err => console.error(err))
Nach dem Login kopieren

Das scheint einfacher zu sein?

Die Async/Await-Version ist immer noch nützlich, wenn Sie eine synchrone Logik mit langer Laufzeit und eine andere asynchrone Aufgabe mit langer Laufzeit in Ihrem Iterator haben

Auf diese Weise können Sie den ersten Wert erhalten Sie können mit einigen Berechnungen beginnen, ohne warten zu müssen, bis alle Versprechen abgeschlossen sind, bevor Sie Ihre Berechnungen ausführen. Obwohl das Ergebnis in ein Promise verpackt ist, ist es schneller, wenn die Ergebnisse nacheinander ausgeführt werden.

Fragen zum Filter

你可能发觉了,即使上面filter函数里面返回了 [ false, true, false, true ] , await asyncThing(value) 会返回一个 promise 那么你肯定会得到一个原始的值。你可以在return之前等待所有异步完成,在进行过滤。

Reducing很简单,有一点需要注意的就是需要将初始值包裹在 Promise.resolve 中

重写基于callback的node应用成

Async 函数默认返回一个 Promise ,所以你可以使用 Promises 来重写任何基于 callback 的函数,然后 await 等待他们执行完毕。在node中也可以使用 util.promisify 函数将基于回调的函数转换为基于 Promise 的函数

重写基于Promise的应用程序

要转换很简单, .then 将Promise执行流串了起来。现在你可以直接使用`async/await。

function asyncTask () {
 return functionA()
  .then((valueA) => functionB(valueA))
  .then((valueB) => functionC(valueB))
  .then((valueC) => functionD(valueC))
  .catch((err) => logger.error(err))
}
Nach dem Login kopieren

转换后

async function asyncTask () {
 try {
  const valueA = await functionA()
  const valueB = await functionB(valueA)
  const valueC = await functionC(valueB)
  return await functionD(valueC)
 } catch (err) {
  logger.error(err)
 }
}
Rewriting Nod
Nach dem Login kopieren

使用 Async/Await 将很大程度上的使应用程序具有高可读性,降低应用程序的处理复杂度(如:错误捕获),如果你也使用 node v8+的版本不妨尝试一下,或许会有新的收获。

相关推荐:

ES6之async+await 同步/异步方案

NodeJs通过async和await处理异步的方法

ES7的async/await用法实例详解

Das obige ist der detaillierte Inhalt vonAsync- und Await-Funktionsanalyse in Node.js. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
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

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

Java-Tutorial
1663
14
PHP-Tutorial
1264
29
C#-Tutorial
1237
24
So implementieren Sie ein Online-Spracherkennungssystem mit WebSocket und JavaScript So implementieren Sie ein Online-Spracherkennungssystem mit WebSocket und JavaScript Dec 17, 2023 pm 02:54 PM

So implementieren Sie mit WebSocket und JavaScript ein Online-Spracherkennungssystem. Einführung: Mit der kontinuierlichen Weiterentwicklung der Technologie ist die Spracherkennungstechnologie zu einem wichtigen Bestandteil des Bereichs der künstlichen Intelligenz geworden. Das auf WebSocket und JavaScript basierende Online-Spracherkennungssystem zeichnet sich durch geringe Latenz, Echtzeit und plattformübergreifende Eigenschaften aus und hat sich zu einer weit verbreiteten Lösung entwickelt. In diesem Artikel wird erläutert, wie Sie mit WebSocket und JavaScript ein Online-Spracherkennungssystem implementieren.

WebSocket und JavaScript: Schlüsseltechnologien zur Implementierung von Echtzeitüberwachungssystemen WebSocket und JavaScript: Schlüsseltechnologien zur Implementierung von Echtzeitüberwachungssystemen Dec 17, 2023 pm 05:30 PM

WebSocket und JavaScript: Schlüsseltechnologien zur Realisierung von Echtzeit-Überwachungssystemen Einführung: Mit der rasanten Entwicklung der Internet-Technologie wurden Echtzeit-Überwachungssysteme in verschiedenen Bereichen weit verbreitet eingesetzt. Eine der Schlüsseltechnologien zur Erzielung einer Echtzeitüberwachung ist die Kombination von WebSocket und JavaScript. In diesem Artikel wird die Anwendung von WebSocket und JavaScript in Echtzeitüberwachungssystemen vorgestellt, Codebeispiele gegeben und deren Implementierungsprinzipien ausführlich erläutert. 1. WebSocket-Technologie

Verwendung von JavaScript und WebSocket zur Implementierung eines Echtzeit-Online-Bestellsystems Verwendung von JavaScript und WebSocket zur Implementierung eines Echtzeit-Online-Bestellsystems Dec 17, 2023 pm 12:09 PM

Einführung in die Verwendung von JavaScript und WebSocket zur Implementierung eines Online-Bestellsystems in Echtzeit: Mit der Popularität des Internets und dem Fortschritt der Technologie haben immer mehr Restaurants damit begonnen, Online-Bestelldienste anzubieten. Um ein Echtzeit-Online-Bestellsystem zu implementieren, können wir JavaScript und WebSocket-Technologie verwenden. WebSocket ist ein Vollduplex-Kommunikationsprotokoll, das auf dem TCP-Protokoll basiert und eine bidirektionale Kommunikation zwischen Client und Server in Echtzeit realisieren kann. Im Echtzeit-Online-Bestellsystem, wenn der Benutzer Gerichte auswählt und eine Bestellung aufgibt

So implementieren Sie ein Online-Reservierungssystem mit WebSocket und JavaScript So implementieren Sie ein Online-Reservierungssystem mit WebSocket und JavaScript Dec 17, 2023 am 09:39 AM

So implementieren Sie ein Online-Reservierungssystem mit WebSocket und JavaScript. Im heutigen digitalen Zeitalter müssen immer mehr Unternehmen und Dienste Online-Reservierungsfunktionen bereitstellen. Es ist von entscheidender Bedeutung, ein effizientes Online-Reservierungssystem in Echtzeit zu implementieren. In diesem Artikel wird erläutert, wie Sie mit WebSocket und JavaScript ein Online-Reservierungssystem implementieren, und es werden spezifische Codebeispiele bereitgestellt. 1. Was ist WebSocket? WebSocket ist eine Vollduplex-Methode für eine einzelne TCP-Verbindung.

JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems Dec 17, 2023 pm 05:13 PM

JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems Einführung: Heutzutage ist die Genauigkeit von Wettervorhersagen für das tägliche Leben und die Entscheidungsfindung von großer Bedeutung. Mit der Weiterentwicklung der Technologie können wir genauere und zuverlässigere Wettervorhersagen liefern, indem wir Wetterdaten in Echtzeit erhalten. In diesem Artikel erfahren Sie, wie Sie mit JavaScript und WebSocket-Technologie ein effizientes Echtzeit-Wettervorhersagesystem aufbauen. In diesem Artikel wird der Implementierungsprozess anhand spezifischer Codebeispiele demonstriert. Wir

Einfaches JavaScript-Tutorial: So erhalten Sie den HTTP-Statuscode Einfaches JavaScript-Tutorial: So erhalten Sie den HTTP-Statuscode Jan 05, 2024 pm 06:08 PM

JavaScript-Tutorial: So erhalten Sie HTTP-Statuscode. Es sind spezifische Codebeispiele erforderlich. Vorwort: Bei der Webentwicklung ist häufig die Dateninteraktion mit dem Server erforderlich. Bei der Kommunikation mit dem Server müssen wir häufig den zurückgegebenen HTTP-Statuscode abrufen, um festzustellen, ob der Vorgang erfolgreich ist, und die entsprechende Verarbeitung basierend auf verschiedenen Statuscodes durchführen. In diesem Artikel erfahren Sie, wie Sie mit JavaScript HTTP-Statuscodes abrufen und einige praktische Codebeispiele bereitstellen. Verwenden von XMLHttpRequest

So verwenden Sie insertBefore in Javascript So verwenden Sie insertBefore in Javascript Nov 24, 2023 am 11:56 AM

Verwendung: In JavaScript wird die Methode insertBefore() verwendet, um einen neuen Knoten in den DOM-Baum einzufügen. Diese Methode erfordert zwei Parameter: den neuen Knoten, der eingefügt werden soll, und den Referenzknoten (d. h. den Knoten, an dem der neue Knoten eingefügt wird).

JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Bildverarbeitungssystems JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Bildverarbeitungssystems Dec 17, 2023 am 08:41 AM

JavaScript ist eine in der Webentwicklung weit verbreitete Programmiersprache, während WebSocket ein Netzwerkprotokoll für die Echtzeitkommunikation ist. Durch die Kombination der leistungsstarken Funktionen beider können wir ein effizientes Echtzeit-Bildverarbeitungssystem erstellen. In diesem Artikel wird erläutert, wie dieses System mithilfe von JavaScript und WebSocket implementiert wird, und es werden spezifische Codebeispiele bereitgestellt. Zunächst müssen wir die Anforderungen und Ziele des Echtzeit-Bildverarbeitungssystems klären. Angenommen, wir haben ein Kameragerät, das Bilddaten in Echtzeit sammeln kann

See all articles