TL; DR: Weil zuvor +=gelesen x, aber geschrieben, nachdem es sich geändert hat, aufgrund des awaitSchlüsselworts in seinem zweiten Operanden (rechts).
asyncFunktionen werden synchron ausgeführt, wenn sie bis zur ersten awaitAnweisung aufgerufen werden .
Wenn Sie also entfernen await, verhält es sich wie eine normale Funktion (mit der Ausnahme, dass es immer noch ein Versprechen zurückgibt).
In diesem Fall erhalten Sie 5und 6in der Konsole:
let x = 0;
async function test() {
x += 5;
console.log('x :', x);
}
test();
x += 1;
console.log('x :', x);
Der erste awaitVorgang stoppt die synchrone Ausführung, auch wenn sein Argument synchron verfügbar ist. Daher wird Folgendes zurückgegeben 1und 6wie erwartet:
let x = 0;
async function test() {
// Enter asynchrony
await 0;
x += 5;
console.log('x :', x);
}
test();
x += 1;
console.log('x :', x);
Ihr Fall ist jedoch etwas komplizierter.
Sie haben awaiteinen Ausdruck eingefügt, der verwendet +=.
Sie wissen wahrscheinlich, dass in JS x += yidentisch ist mit x = (x + y). Ich werde das letztere Formular zum besseren Verständnis verwenden:
let x = 0;
async function test() {
x = (x + await 5);
console.log('x :', x);
}
test();
x += 1;
console.log('x :', x);
Wenn der Dolmetscher diese Zeile erreicht ...
x = (x + await 5);
... es beginnt es zu bewerten und es dreht sich um ...
x = (0 + await 5);
... dann erreicht es das awaitund hört auf.
Der Code nach dem Funktionsaufruf wird ausgeführt, ändert den Wert von xund protokolliert ihn anschließend.
xist jetzt 1.
Nach dem Beenden des Hauptskripts kehrt der Interpreter zur angehaltenen testFunktion zurück und setzt die Auswertung dieser Zeile fort:
x = (0 + 5);
Und da der Wert von xbereits ersetzt ist, bleibt er bestehen 0.
Schließlich führt der Interpreter die Addition durch, speichert 5sie xund protokolliert sie.
Sie können dieses Verhalten überprüfen, indem Sie sich in einem Objekt-Eigenschafts-Getter / -Setter anmelden (in diesem Beispiel wird y.zder Wert von x:
let x = 0;
const y = {
get z() {
console.log('get x :', x);
return x;
},
set z(value) {
console.log('set x =', value);
x = value;
}
};
async function test() {
console.log('inside async function');
y.z += await 5;
console.log('x :', x);
}
test();
console.log('main script');
y.z += 1;
console.log('x :', x);
/* Output:
inside async function
get x : 0 <-- async fn reads
main script
get x : 0
set x = 1
x : 1
set x = 5 <-- async fn writes
x : 5 <-- async fn logs
*/
/* Just to make console fill the available space */
.as-console-wrapper {
max-height: 100% !important;
}
await (x += 5)und kennenx += await 5.