Theorie
Native asyncFunktionen können bei der Konvertierung in Zeichenfolgen identifiziert werden :
asyncFn[Symbol.toStringTag] === 'AsyncFunction'
Oder vom AsyncFunctionKonstruktor:
const AsyncFunction = (async () => {}).constructor;
asyncFn instanceof AsyncFunction === true
Dies funktioniert nicht mit der Babel / TypeScript-Ausgabe, da asyncFnes sich bei der regulären Funktion im transpilierten Code um eine Instanz von Functionoder GeneratorFunctionnicht handelt AsyncFunction. Um sicherzustellen, dass im transpilierten Code keine Fehlalarme für Generator- und reguläre Funktionen ausgegeben werden:
const AsyncFunction = (async () => {}).constructor;
const GeneratorFunction = (function* () => {}).constructor;
(asyncFn instanceof AsyncFunction && AsyncFunction !== Function && AsyncFunction !== GeneratorFunction) === true
Da native asyncFunktionen 2017 offiziell in Node.js eingeführt wurden, bezieht sich die Frage wahrscheinlich auf die Babel-Implementierung von asyncFunktionen, die sich auf transform-async-to-generatordas Transpilieren asyncin Generatorfunktionen stützen und möglicherweise auch transform-regeneratorzum Transpilieren von Generatoren in reguläre Funktionen verwendet werden.
Das Ergebnis des asyncFunktionsaufrufs ist ein Versprechen. Dem Vorschlag zufolge kann ein Versprechen oder ein Nichtversprechen weitergegeben werden await, await callback()was universell ist.
Es gibt nur wenige Randfälle, in denen dies erforderlich sein kann. Zum Beispiel verwenden native asyncFunktionen native Versprechen intern und greifen nicht global auf, Promisewenn ihre Implementierung geändert wurde:
let NativePromise = Promise;
Promise = CustomPromiseImplementation;
Promise.resolve() instanceof Promise === true
(async () => {})() instanceof Promise === false;
(async () => {})() instanceof NativePromise === true;
Dies kann das Funktionsverhalten beeinflussen (dies ist ein bekanntes Problem für die Implementierung von Angular und Zone.js Versprechen ). Selbst dann ist es vorzuziehen, zu erkennen, dass der Funktionsrückgabewert nicht als PromiseInstanz erwartet wird, anstatt zu erkennen, dass es sich um eine Funktion handelt async, da dasselbe Problem auf jede Funktion anwendbar ist, die eine alternative Versprechenimplementierung verwendet, und nicht nur async( die Lösung für dieses Winkelproblem besteht darin, die asyncRückgabe zu verpacken Wert mit Promise.resolve).
Trainieren
Von außen ist asyncFunktion nur eine Funktion, die bedingungslos native Versprechen zurückgibt, daher sollte sie wie eine behandelt werden. Selbst wenn eine Funktion einmal definiert wurde async, kann sie irgendwann transpiliert werden und zu einer regulären Funktion werden.
Eine Funktion, die ein Versprechen zurückgeben kann
In ES6 kann eine Funktion, die möglicherweise ein Versprechen zurückgibt, mit Promise.resolve(lässt synchrone Fehler) oder einem umschlossenen PromiseKonstruktor (behandelt synchrone Fehler) verwendet werden:
Promise.resolve(fnThatPossiblyReturnsAPromise())
.then(result => ...);
new Promise(resolve => resolve(fnThatPossiblyReturnsAPromiseOrThrows()))
.then(result => ...);
In ES2017 geschieht dies mit await(so soll das Beispiel aus der Frage geschrieben werden):
let result = await fnThatPossiblyReturnsAPromiseOrThrows();
...
Eine Funktion, die ein Versprechen zurückgeben sollte
Die Überprüfung, ob ein Objekt ein Versprechen ist, ist eine separate Frage , sollte jedoch im Allgemeinen nicht zu streng oder locker sein, um Eckfälle abzudecken. instanceof Promisefunktioniert möglicherweise nicht, wenn global Promiseersetzt wurde Promise !== (async () => {})().constructor. Dies kann passieren, wenn Angular- und Nicht-Angular-Anwendungen eine Schnittstelle bilden.
Eine Funktion, die erforderlich ist async, dh immer ein Versprechen zurückzugeben, sollte zuerst aufgerufen werden. Anschließend wird der zurückgegebene Wert als Versprechen überprüft:
let promise = fnThatShouldReturnAPromise();
if (promise && typeof promise.then === 'function' && promise[Symbol.toStringTag] === 'Promise') {
} else {
throw new Error('async function expected');
}
TL; DR: asyncFunktionen sollten nicht von regulären Funktionen unterschieden werden, die Versprechen zurückgeben. Es gibt keinen zuverlässigen Weg und keinen praktischen Grund, nicht native transpilierte asyncFunktionen zu erkennen .
awaitein Nicht-Versprechen haben, wird es trotzdem automatisch verpackt)