非同期の2つの関数a
とb
があり、前者はawait
なしで、後者はawait
あります。コンソールに何かを記録し、undefined
を返します。関数のいずれかを呼び出した後、別のメッセージを記録し、関数の本体を実行する前または実行した後にメッセージが書き込まれるかどうかを調べます。
function someMath() {
for (let i = 0; i < 3000000; i++) { Math.sqrt(i**5) }
}
function timeout(n) {
return new Promise(cb => setTimeout(cb, n))
}
// ------------------------------------------------- a (no await)
async function a() {
someMath()
console.log('in a (no await)')
}
// ---------------------------------------------------- b (await)
async function b() {
await timeout(100)
console.log('in b (await)')
}
clear.onclick = console.clear
aButton.onclick = function() {
a()
console.log('after a (no await) call')
}
bButton.onclick = function() {
b()
console.log('after b (await) call')
}
<button id="aButton">test without await</button>
<button id="bButton">test with await</button>
<button id="clear">clear console</button>
await
なしでテストを起動すると、関数は同期のように機能するようです。ただし、await
では、関数が非同期に実行されるため、メッセージはinvertedです。
だから私の質問は:javascriptがasync
キーワードが存在しないときにawait
関数を実行する方法ですか?
実際のユースケース:条件付きで実行されるawait
キーワードがあり、関数が同期的に実行されるかどうかを知る必要があります要素をレンダリングする順序:
async function initializeComponent(stuff) {
if (stuff === undefined)
stuff = await getStuff()
// initialize
if (/* context has been blocked */)
renderComponent() // render again if stuff had to be loaded
}
initializeComponent()
renderComponent()
P.S:タイトルにはjavascriptキーワードがあり、他の言語での同じ質問との混同を避けています(つまり awaitなしでasyncを使用 )
mozilla docから:
非同期関数canには、非同期関数の実行を一時停止し、渡されたPromiseの解決を待機してから非同期関数の実行を再開するawait式を含めることができます解決された値を返します。
想定したとおり、待機が存在しない場合、実行は一時停止されず、コードは同期的に実行されます。
Javascript非同期関数が実行されるまで、すべてが同期的です。 async-awaitを使用する場合、await
は非同期であり、awaitの後はすべてイベントキューに配置されます。 .then()
に似ています。
よりよく説明するには、この例を取り上げます。
function main() {
return new Promise( resolve => {
console.log(3);
resolve(4);
console.log(5);
});
}
async function f(){
console.log(2);
let r = await main();
console.log(r);
}
console.log(1);
f();
console.log(6);
await
は非同期であり、残りはpromiseを含むすべて同期であるため、出力は
1
2
3
5
6
// Async happened, await for main()
4
main()
の同様の動作も約束なしです:
function main() {
console.log(3);
return 4;
}
async function f(){
console.log(2);
let r = await main();
console.log(r);
}
console.log(1);
f();
console.log(5);
出力:
1
2
3
5
// Asynchronous happened, await for main()
4
await
を削除するだけで、async
関数全体が同期されます。
function main() {
console.log(3);
return 4;
}
async function f(){
console.log(2);
let r = main();
console.log(r);
}
console.log(1);
f();
console.log(5);
出力:
1
2
3
4
5
関数は、await
の有無にかかわらず同じように実行されます。 await
が行うことは、関数によって返されるpromiseが解決されるのを自動的に待つことです。
await timeout(1000);
more code here;
以下とほぼ同等です。
timeout(1000).then(function() {
more code here;
});
async function
宣言は、関数が戻るときに解決されるプロミスを関数が自動的に返すようにします。