webentwicklung-frage-antwort-db.com.de

sollten wir async über Promise in Javascript erwarten

Ich weiß, dass der async await die neue Promise in der Stadt ist, und es ist eine neue Art, asynchronen Code zu schreiben, und das weiß ich auch

Wir mussten nicht .then schreiben, sondern eine anonyme Funktion erstellen, um die Antwort zu bearbeiten

Async/await macht es endlich möglich, sowohl synchrone als auch asynchrone Fehler mit demselben Konstrukt zu behandeln, also gut alt try/catch

Der von einer promise-Kette zurückgegebene Fehlerstapel gibt keinen Hinweis darauf, wo der Fehler aufgetreten ist. Der Fehlerstack von async/await verweist jedoch auf die Funktion, die den Fehler enthält

UND SO EIN ...

aber hier habe ich eine einfache Benchmark erstellt https://repl.it/repls/FormalAbandonedChimpanzee

Im Benchmark habe ich 1 Million Mal 2 Schleifen ausgeführt. In der ersten Schleife rufe ich eine Funktion auf, die 1 Zurückgibt. In einer anderen Funktion rufe ich eine Funktion auf, die als Ausnahme 1 auslöst .

die Zeit, die die erste Schleife benötigt, die eine Funktion aufruft, die 1 zurückgibt, ist fast die Hälfte der Funktion, die 1 als Fehler auslöst.

Dies zeigt, dass die Zeit von throw fast doppelt so lang ist wie die von return.

node v7.4 linux/AMD64

return takes 1.233seconds
1000000
throw takes 2.128seconds
1000000

Benchmark-Code unten

function f1() {
  return 1;
}

function f2() {
  throw 1;
}

function parseHrtimeToSeconds(hrtime) {
    var seconds = (hrtime[0] + (hrtime[1] / 1e9)).toFixed(3);
    return seconds;
}

var sum = 0;
var start = 0;
var i = 0;

start = process.hrtime();
for (i = 0; i < 1e6; i++) {
  try {
    sum += f1();
  } catch (e) {
    sum += e;
  }
}
var seconds = parseHrtimeToSeconds(process.hrtime(start));
console.log('return takes ' + seconds + 'seconds');
console.log(sum);




sum = 0;
start = process.hrtime();
for (i = 0; i < 1e6; i++) {
  try {
    sum += f2();
  } catch (e) {
    sum += e;
  }
}

seconds = parseHrtimeToSeconds(process.hrtime(start));
console.log('throw takes ' + seconds + 'seconds');
console.log(sum);
8
Vikas Bansal

Ihr Benchmark hat nichts mit der Performance zwischen async/await und rohen Versprechen zu tun. Alles was ich sehen kann ist, dass das Berechnen eines Fehlers länger dauert. Das wird erwartet.

Zurück zur Hauptfrage: Verwenden Sie async/await anstelle von .then mit reinen Versprechen.

Denken Sie daran, dass async/await nur syntaktischer Zucker über rohen Versprechen ist, daher sollte die Gesamtleistung nicht wesentlich beeinflusst werden. Allerdings wird Ihr Code dadurch linearer, was dem Entwickler viel kognitiven Aufwand erspart.

Die Schlussfolgerung ist, was Sie bevorzugen. Versprechen können mehrfach gefüllt werden, neue Syntaxe jedoch nicht. Daher sollten Sie dies bei der Auswahl des zu verwendenden Stils beachten.


Ein Missverständnis:

Der von einer Versprechungskette zurückgegebene Fehlerstapel gibt keinen Hinweis darauf, wo der Fehler aufgetreten ist

Das ist nicht wahr. Ein kurzer Check bei:

function error() {
    return new Promise(function(res, rej) {
        res(undefined()); // uh oh
    });
}

error().then(console.log, e => console.log("Uh oh!", e.stack));

zeigt den gesamten Fehlerstapel einschließlich der Position an.

12

Wie die meisten Dinge gehen, lautet die Antwort "es kommt darauf an".

Bevor wir über Leistung sprechen, ist der wichtigste Aspekt die Wartbarkeit des Codes und die Einschränkung von async/await im Vergleich zu raw Promise.

Mit async/await können Sie asynchronen Code sequentiell ausführen. Mit Promise können Sie asynchronen Code gleichzeitig ausführen.

async function foo() {
  const a = await backend.doSomething()
  const b = await backend.doAnotherThing()
  return a + b
}

Im obigen Code wird backend.doAnotherThing() erst ausgeführt, nachdem backend.doSomething() zurückgekehrt ist. Auf der anderen Seite:

function foo() {
  Promise.all([backend.doSomething(), backend.doAnotherThing()])
    .then(([a, b]) => {
       return a + b
    })
}

führt beide Aufrufe aus und wartet, bis beide abgeschlossen sind.

Wie Sie bereits über die Vorteile von async/await gesprochen haben, benutze ich sie persönlich ausführlich. Mit Ausnahme der oben genannten Fälle.

Wenn Sie Leistung benötigen und für Sie wichtig sind, ist der Leistungsunterschied zwischen async/await und Promise wichtiger als der Lesbarkeitsvorteil von async/await über Promise.

Solange es eine bewusste Entscheidung ist, sollte es Ihnen gut gehen.

UPDATE: wie von Derek mentioned erwähnt

Sie können die parallele Ausführung mit async/await folgendermaßen erhalten:

async function foo() {
  const p1 = backend.doSomething()
  const p2 = backend.doAnotherThing()
  return await p1 + await p2
}
7
unional

Aufbauend auf die Antwort von unional :

Sie können dasselbe Verhalten wie Promise.all mit async/await erreichen.

function foo() {
  Promise.all([backend.doSomething(), backend.doAnotherThing()])
    .then(([a, b]) => {
       return a + b
    })
}

async function foo() {
  const a = backend.doSomething()
  const b = backend.doAnotherThing()
  return await a + await b
}

Backend-Aufgaben finden gleichzeitig statt und wir warten darauf, dass beide abgeschlossen sind, bevor wir zurückkehren. Siehe auch das MDN-Beispiel, das ich geschrieben habe

Aufgrund dessen bin ich nicht sicher, ob es einen Leistungsvorteil für die direkte Verwendung von Promises gegenüber async/await gibt. 

1
spygi