Heim  >  Artikel  >  Web-Frontend  >  Die Besonderheiten von async/await

Die Besonderheiten von async/await

hzc
hzcnach vorne
2020-06-15 09:53:162706Durchsuche

Vorwort

Während des Interviews ist Async/Await ein guter Indikator für das Wissen des Kandidaten. Natürlich habe ich nicht darüber nachgedacht, aus welchem ​​Blickwinkel ich diesen Wissenspunkt erklären soll. Auf die Frage des Interviewers können Sie mit der Syntax des selbstausführenden Generators antworten. Aber habe ich es ein wenig erkannt, oder habe ich seine Erkenntnis gesehen?

Wie Babel implementiert wird

Hinweis: Wenn Sie sich mit Generator nicht auskennen, können Sie sich zuerst den Generator und übrigens auch den Iterator ansehen.

Ex-Code:

async function t() {
    const x = await getResult();
  	const y = await getResult2();
  	return x + y;
}

Babel-Konvertierungscode

"use strict";

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
    try {
        var info = gen[key](arg);
        var value = info.value;
    } catch (error) {
        reject(error);
        return;
    }
    if (info.done) {
        resolve(value);
    } else {
        Promise.resolve(value).then(_next, _throw);
    }
}

function _asyncToGenerator(fn) {
    return function () {
        var self = this, args = arguments;
        return new Promise(function (resolve, reject) {
            var gen = fn.apply(self, args);
            function _next(value) {
                asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
            }
            function _throw(err) {
                asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
            }
            _next(undefined);
        });
    };
}

function t() {
  return _t.apply(this, arguments);
}

function _t() {
  _t = _asyncToGenerator(function* () {
    const x = yield getResult();
    const y = yield getResult2();
    return x + y;
  });
  return _t.apply(this, arguments);
}

Wie aus dem Code ersichtlich ist, benötigt babel zwei Schritte, um ein generator in ein umzuwandeln async _asyncToGenerator und asyncGeneratorStep.

Was hat _asyncToGenerator getan?

1. Der Aufruf von _asyncToGenerator hat ein promise zurückgegeben, was genau den Eigenschaften entspricht, mit denen die Funktion async verbunden werden kann 🎜>. then

2. Definieren Sie eine erfolgreiche Methode

und definieren Sie eine fehlgeschlagene Methode _next. In den beiden Funktionen wird _throw aufgerufen. Nachdem Sie asyncGeneratorStep gelesen haben, werden Sie wissen, dass es sich tatsächlich um eine Rekursion handelt. asyncGeneratorStep

3. Ausführen

. Das ist der oben erwähnte selbstausführende Generator. _next

Was hat es bewirkt?asyncGeneratorStep

1. Try-Catch, um Fehler während der Ausführung von

zu erfassen. Wird ein Fehler gemeldet, wechselt die Funktion generator direkt in den Status async. reject

2. Bestimmen Sie, ob der

-Wert in info wahr ist. Wenn er wahr ist, bedeutet dies, dass der Iterator ausgeführt wurde und der Wert done ausgegeben werden kann. Andernfalls rufen Sie weiterhin resolve auf, um den Wert an den nächsten zu übergeben. _next

这里我唯一没有看明白的是`_throw`,这个看代码像是执行不到的。promise.resolve状态值应该是fulfilled。看懂的
可以在评论中和我说一下,感谢。

Vorteile von async/await

Jedes Mal, wenn ein neuer syntaktischer Zucker erscheint, muss er die Mängel der Lösung der vorherigen Generation ausgleichen.

Beispiel: Das Aufkommen von

Versprechen besteht darin, es zu vermeiden

. callback hell

Was löst async/await?


Die Notwendigkeit, Versprechen durch async/await zu ersetzen

Asynchrone Synchronisation auf synchrone Weise handhaben

async/await ist näher am Synchronisationsstil, while Promise verwendet die Then-Methode, der Code wird größer und es gibt keinen großen Unterschied zwischen Async/Await- und Synchronisationsfunktionen. Es gibt jedoch immer noch eine Lücke in der Schreibmethode von Promise.

Promise- und Async/Wait-Code-Vergleich

Promise-Version

function getData() {
    getRes().then((res) => {
        console.log(res);
    })
}

async/await-Version

const getData = async function() {
    const res = await getRes();
    console.log(res);
}

Zwischenwert

Bei der Verwendung von Versprechen werden Sie feststellen, dass es bei der Serialisierung mehrerer Versprechen sehr schwierig ist, dass das nachfolgende Versprechen den Wert des vorherigen Versprechens erhält. Und async löst genau dieses Problem.

Beispiel für das Versprechen, einen Zwischenwert zu erhalten

const morePromise = () => {
	return promiseFun1().then((value1) => {
		return promiseFun2(value1).then((value2) => {
			return promiseFun3(value1, value2).then((res) => {
				console.log(res);
			})
		}) 
	})
}

Das Obige ist eine verschachtelte Version, die möglicherweise nicht entsprechend unterschiedlichen Anforderungen verschachtelt wird.

const morePromise = () => {
	return promiseFun1().then((value1) => {
		return promiseAll([value1, promiseFun2(value1)])
	}).then(([value1, value2]) => {
		return promiseFun3(value1, value2).then((res) => {
			console.log(res);
		})
	})
}

Weniger Verschachtelungsebenen, aber immer noch nicht zufriedenstellend.

Beispiel zur Optimierung von async/await

const morePromise = async function() {
	const value1 = await promiseFun1();
	const value2 = await promiseFun2(value1);
	const res = await promiseFun3(value1, valuw2);
	return res;
}

Serielle asynchrone Prozesse müssen Zwischenwerte beinhalten, daher liegen die Vorteile von async/await auf der Hand.

Bedingte Anweisungssituation

Beispielsweise besteht aktuell ein Bedarf. Nachdem Sie ein Datenelement angefordert haben, können Sie dann feststellen, ob Sie weitere Daten anfordern müssen. Bei der Implementierung mithilfe von Versprechen gibt es weiterhin verschachtelte Ebenen.

const a = () => {
    return getResult().then((data) => {
        if(data.hasMore) {
            return getMoreRes(data).then((dataMore) => {
                return dataMore;
            })
        } else {
            return data;
        }
    })
}

Aber die Verwendung von Async zur Optimierung dieses Beispiels kann den Code schöner machen.

Async/await-Optimierungsbeispiele

const a = async() => {
    const data = await getResult();
    if(data.hasMore) {
        const dataMore = await getMoreRes(data);
        return dataMore;
    } else {
        return data;
    }
}

Nachteile von async/await

Wir haben oben über einige der Vorteile von async/await gesprochen, aber async/await ist nicht allmächtig . . Bei den oben genannten Themen handelt es sich ausschließlich um serielle asynchrone Szenarien. Wenn wir uns in ein paralleles asynchrones Szenario verwandeln. Es ist weiterhin notwendig, Promise.all zu verwenden, um

parallele asynchrone Szenarien

const a = async function() {
    const res = await Promise.all[getRes1(), getRes2()];
    return res;
}

async/await-Fehlerbehandlung

async/await bei der Fehlererfassung zu implementieren Der Hauptaspekt ist Try-Catch.

Try-Catch

const a = async () => {
    try{
        const res = await Promise.reject(1);
    } catch(err) {
        console.log(err);
    }
}

Promise's Catch

kann eine öffentliche Funktion extrahieren, um dies zu tun. Da auf jedes Versprechen eine Catch-Verarbeitung folgt, ist der Code sehr lang.

const a = async function() {
    const res = await Promise.reject(1).catch((err) => {
        console.log(err);
    })
}
rrree

Empfohlenes Tutorial: „

JS-Tutorial

Das obige ist der detaillierte Inhalt vonDie Besonderheiten von async/await. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen