Detaillierte Erklärung asynchroner Iteratoren in nodejs

Detaillierte Erklärung asynchroner Iteratoren in nodejs

Vorwort

Asynchrone Iteratoren gibt es seit Node.js v10.0.0 und sie haben in der Community in letzter Zeit an Bedeutung gewonnen. In diesem Artikel diskutieren wir die Rolle asynchroner Iteratoren und gehen auch auf die Frage ein, wofür sie verwendet werden könnten.

Was sind asynchrone Iteratoren?

Was sind also asynchrone Iteratoren? Sie sind effektiv asynchrone Versionen der Iteratoren, die zuvor verfügbar waren. Wenn wir den Wert und den Endstatus der Iteration nicht kennen, können wir asynchrone Iteratoren verwenden und erhalten schließlich ein Versprechen, das in ein {value:any, done:boolean}-Objekt aufgelöst werden kann. Wir haben außerdem eine For-Await-Of-Schleife, die uns beim Durchlaufen asynchroner Iteratoren hilft. Genauso wie eine For-of-Schleife für synchrone Iteratoren.

asyncIterable = [1, 2, 3];
asyncIterable[Symbol.asyncIterator] = asynchrone Funktion*() {
  für (lass i = 0; i < asyncIterable.length; i++) {
    Ertrag { Wert: asyncIterable[i], fertig: false }
  }
  Ertrag { erledigt: wahr };
};

(asynchrone Funktion() {
  für await (const Teil von asyncIterable) {
    konsole.log(Teil);
  }
})();

Im Gegensatz zu einer normalen For-of-Schleife wartet eine For-Await-of-Schleife auf die Einlösung jedes empfangenen Versprechens, bevor mit dem nächsten fortgefahren wird.

Außer Streams gibt es derzeit nicht viele Strukturen, die asynchrone Iteration unterstützen, aber die Notation kann wie hier gezeigt manuell zu jeder iterierbaren Struktur hinzugefügt werden.

Als asynchroner Iterator-Stream

Asynchrone Iteratoren sind bei der Verarbeitung von Streams sehr nützlich. Lesbare, beschreibbare, Duplex- und Transform-Streams unterstützen alle asynchrone Iteratoren.

asynchrone Funktion printFileToConsole(Pfad) {
  versuchen {
    const readStream = fs.createReadStream(Pfad, { Kodierung: 'utf-8' });

    für warten (const chunk of readStream) {
      Konsole.log(Block);
    }

    console.log('EOF');
  } fange(Fehler) {
    konsole.log(Fehler);
  }
}

Wenn Sie Ihren Code auf diese Weise schreiben, müssen Sie beim Durchlaufen der Iteration zum Abrufen jedes Datenblocks nicht auf die Daten und Endereignisse achten, und die For-Await-Of-Schleife endet, wenn der Stream selbst endet.

Aufrufen einer API mit Paging-Funktionalität

Sie können auch asynchrone Iteration verwenden, um Daten einfach aus Quellen abzurufen, die Paginierung verwenden. Dazu benötigen wir auch eine Möglichkeit, den Antworttext aus dem Stream zu rekonstruieren, den uns die Node-HTTPS-Anforderungsmethode liefert. Sie können hier auch asynchrone Iteratoren verwenden, da HTTPS-Anfragen und -Antworten in Node Streams sind:

const https = erfordern('https');

Funktion homebrewFetch(URL) {
  returniere neues Promise(async (auflösen, ablehnen) => {
    const req = https.get(url, async-Funktion(res) {
      wenn (res.statusCode >= 400) {
        Rückgabe ablehnen (neuer Fehler („HTTP-Status: ${res.statusCode}“));
      }

      versuchen {
        lass body = '';

        /*
          Anstatt res.on auf Daten im Stream zu warten,
          Wir können for-await-of verwenden und den Datenblock anhängen
          zum Rest des Antworttexts*/
        für warten (const chunk of res) {
          Körper += Block;
        }
    
        // Behandeln Sie den Fall, dass kein Textkörper vorhanden ist, wenn (!body) resolve({});
        // Wir müssen den Text analysieren, um das JSON zu erhalten, da es sich um einen String handelt. const result = JSON.parse(body);
        Lösung (Ergebnis);
      } fange(Fehler) {
        ablehnen(Fehler)
      }
    });

    warte auf Anforderung;
    erforderlich.ende();
  });
}

Wir werden eine Anfrage an die Cat-API stellen, um einige Katzenbilder in Gruppen von 10 zu erhalten. Wir werden außerdem eine Verzögerung von 7 Sekunden zwischen den Anfragen mit einer maximalen Seitenzahl von 5 hinzufügen, um eine Überlastung der Cat-API zu vermeiden.

Wir werden außerdem eine Verzögerung von 7 Sekunden zwischen den Anfragen und maximal 5 Seiten hinzufügen, um eine Überlastung der Cat-API zu vermeiden, da dies katastrophale Folgen hätte.

Funktion fetchCatPics({ Limit, Seite, fertig }) {
  returniere homebrewFetch(`https://api.thecatapi.com/v1/images/search?limit=${limit}&page=${page}&order=DESC`)
    .then(body => ({ value: body, fertig }));
}

Funktion catPics({ Limit }) {
  zurückkehren {
    [Symbol.asyncIterator]: asynchrone Funktion*() {
      lass aktuelleSeite = 0;
      // Nach 5 Seiten stoppen
      während(aktuelleSeite < 5) {
        versuchen {
          const cats = warte auf fetchCatPics({ aktuelleSeite, limit, fertig: false });
          console.log(`${limit} Katzen abgerufen`);
          Katzen ausbeuten;
          aktuelleSeite++;
        } fange(Fehler) {
          console.log('Beim Abrufen aller Katzen ist ein Fehler aufgetreten!');
          konsole.log(Fehler);
        }
      }
    }
  };
}

(asynchrone Funktion() {
  versuchen {
    für await (let catPicPage of catPics({ limit: 10 })) {
      Konsole.log(catPicPage);
      // Warten Sie 7 Sekunden zwischen den Anfragen
      warte auf neues Promise(resolve => setTimeout(resolve, 7000));
    }
  } fange(Fehler) {
    konsole.log(Fehler);
  }
})()

Auf diese Weise holen wir automatisch alle 7 Sekunden eine ganze Seite mit Katzenbildern für Sie ab.

Eine gängigere Methode zum Navigieren zwischen Seiten besteht darin, die Methoden „next“ und „previous“ zu implementieren und sie als Steuerelemente verfügbar zu machen:

Funktion tatsächlicheKatzenbilder({ Grenze }) {
  zurückkehren {
    [Symbol.asyncIterator]: () => {
      lass Seite = 0;
      zurückkehren {
        weiter: Funktion() {
          Seite++;
          returniere fetchCatPics({Seite, Limit, fertig: false});
        },
        vorherige: function() {
          if (Seite > 0) {
            Seite--;
            returniere fetchCatPics({Seite, Limit, fertig: false});
          }
          returniere fetchCatPics({Seite: 0, Limit, fertig: true});
        }
      }
    }
  };
}

versuchen {
    const einigeKatzenbilder = tatsächlicheKatzenbilder({ limit: 5 });
    const { nächstes, vorheriges } = einigeKatzenbilder[Symbol.asyncIterator]();
    weiter().dann(console.log);
    weiter().dann(Konsole.log);
    vorherige().dann(Konsole.log);
} fange(Fehler) {
  konsole.log(Fehler);
}

Wie Sie sehen, sind asynchrone Iteratoren sehr nützlich, wenn Sie Seiten mit Daten abrufen oder beispielsweise unendliches Scrollen auf der Benutzeroberfläche Ihrer Anwendung ausführen möchten.

Diese Funktionen sind in Browsern seit einiger Zeit verfügbar und zwar in Chrome v63+, Firefox v57+ und Safari v11.1. Derzeit ist es jedoch in IE und Edge nicht verfügbar.

Oben finden Sie eine ausführliche Erläuterung des asynchronen Iterators in nodejs. Weitere Informationen zum asynchronen Iterator von nodejs finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • Fehlerbehebung bei hohem Speicherverbrauch von NodeJs, tatsächlicher Kampfrekord
  • Detaillierte Erläuterung der Verwendung des in Nodejs integrierten Verschlüsselungsmoduls zur Peer-to-Peer-Verschlüsselung und -Entschlüsselung
  • Detaillierte Erklärung der in Node.js integrierten Module
  • Quellcodeanalyse des Nodejs-Modulsystems
  • Eine kurze Diskussion über ereignisgesteuerte Entwicklung in JS und Nodejs
  • So verwenden Sie das Modul-FS-Dateisystem in Nodejs
  • Zusammenfassung einiger Tipps zum Umgehen der Node.js-Codeausführung
  • Nodejs Exploration: Tiefgreifendes Verständnis des Prinzips der Single-Threaded High Concurrency
  • Nodejs-Fehlerbehandlungsprozessaufzeichnung
  • So schreiben Sie mit nodejs ein Tool zur Generierung von Entitätsklassen für Datentabellen für C#

<<:  Installations-Tutorial für mysql8.0rpm auf centos7

>>:  Detailliertes Tutorial zur Installation von MySQL 8.0 aus dem Quellcode auf CentOS 7.4

Artikel empfehlen

CSS-Overflow-Wrap – Verwendung neuer Eigenschaftswerte überall

1. Verstehen Sie zunächst das Overflow-Wrap-Attri...

Detaillierte Erklärung zur Verwendung der Element-el-button-Button-Komponente

1. Hintergrund Schaltflächen werden sehr häufig v...

Detaillierte Erklärung des JS-Browser-Ereignismodells

Inhaltsverzeichnis Was ist ein Ereignis Ein einfa...

Detaillierte Erklärung langer Transaktionsbeispiele in MySQL

Vorwort: Die Artikelserie „Erste Schritte mit MyS...

So überwachen Sie die Windows-Leistung auf Zabbix

Hintergrundinformationen Ich habe kürzlich einige...

Installations-Tutorial für VMware Workstation 12 Pro Linux

Dieser Artikel zeichnet das Linux-Tutorial zur In...

So verhindern Sie, dass Website-Inhalte in Suchmaschinen aufgenommen werden

Normalerweise besteht das Ziel beim Erstellen ein...

Eine eingehende Analyse von MySQL erläutert die Verwendung und die Ergebnisse

Vorwort Bei unserer täglichen Arbeit führen wir m...

Vue implementiert rekursiv benutzerdefinierte Baumkomponenten

In diesem Artikel wird der spezifische Code der r...

Wie CSS die Zeit des weißen Bildschirms während des ersten Ladens beeinflusst

Rendering-Pipeline mit externen CSS-Dateien In de...

Detaillierte Erläuterung der Redis-Master-Slave-Replikationspraxis mit Docker

Inhaltsverzeichnis 1. Hintergrund 2. Bedienungssc...

So fügen Sie schnell 10 Millionen Datensätze in MySQL ein

Ich habe gehört, dass es eine Interviewfrage gibt...

CSS Sticky Footer Mehrere Implementierungen

Was ist „Sticky Footer“ Der sogenannte „Sticky Fo...