TL; DR: 2番目のオペランド(右側)のキーワードが原因で、変更前に+=読み取りx、変更後に書き込みを行うためawait。
async関数は、最初のawaitステートメントまで呼び出されたときに同期的に実行されます。
したがって、を削除awaitすると、通常の関数のように動作します(ただし、Promiseを返す点が異なります)。
その場合、コンソールで次のように5なります6。
let x = 0;
async function test() {
x += 5;
console.log('x :', x);
}
test();
x += 1;
console.log('x :', x);
最初awaitにも同期的にその引数可能な場合は、その次のことが返され、同期運転を停止1し、6あなたが期待するように、:
let x = 0;
async function test() {
// Enter asynchrony
await 0;
x += 5;
console.log('x :', x);
}
test();
x += 1;
console.log('x :', x);
ただし、ケースはもう少し複雑です。
awaitを使用する式の中に入れました+=。
おそらくご存知でしょうが、JSではx += yと同じですx = (x + y)。理解を深めるために、後者の形式を使用します。
let x = 0;
async function test() {
x = (x + await 5);
console.log('x :', x);
}
test();
x += 1;
console.log('x :', x);
通訳がこの行に達すると...
x = (x + await 5);
...評価を開始し、次のようになります...
x = (0 + await 5);
...その後、到達しawaitて停止します。
関数呼び出し後のコードは実行を開始し、の値を変更してからx、ログに記録します。
xです1。
次に、メインスクリプトが終了すると、インタープリターは一時停止されたtest関数に戻り、その行の評価を続行します。
x = (0 + 5);
また、の値xは既に代入されているため、そのままになり0ます。
最後に、インタプリタは追加を実行し、に格納5しxてログに記録します。
この動作を確認するには、オブジェクトプロパティのゲッター/セッター内でログを記録します(この例でy.zは、の値を反映しています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)ありx += await 5ます。