このJavaScript関数は、whileループを非同期に使用しているようです。非同期条件でwhileループを使用する正しい方法ですか?
var Boo;
var Foo = await getBar(i)
while(Foo) {
Boo = await getBar3(i)
if (Boo) {
// something
}
Foo = await getBar(i)
i++
}
私が思うことはこれです:
var Boo;
var Foo;
getBar(i).then( (a) => {
Foo = a;
if(Foo) {
getBar3(i).then( (a) => {
Boo = a
if(Boo) {
//something
i++;
getBar(i).then( (a} => { Repeat itself...}
}
}
}
})
それが完全に偽の場合、非同期await + whileループでそれを行う別の方法を示すことができますか?
ありがとう!!
非同期条件でwhileループを使用する正しい方法ですか?
はい。 async function
sは、それぞれのpromiseが満たされるまでawait
ごとに実行を一時停止し、すべての制御構造は以前と同様に機能し続けます。
うん、それはこのようにして大丈夫です:
let stopped = false
// infinite loop
while(!stopped) {
let res = await fetch('api link')
if (res.something) stopped = true // stop when you want
}
この質問が出されてからしばらく経ちました。私は長年の他の言語(パンチカードや紙テープで始まる)の後でjsを始めて、この問題を解決する必要がありました。これが私の答えです:
var loopContinue = true;
var n = 0;
async function Managework() {
while (loopContinue) { //seemingly an infinite loop
//await (doWork(n));
await (doWork(n).catch(() => { loopContinue=false; }));
n++;
console.log(`loop counter ${n}`);
}
console.log(`loop exit n=${n} loopContinue=${loopContinue}`);
}
Managework();
function doWork(n) {
return new Promise((resolve, reject) => {
console.log(`dowork(${n})`);
if (n > 5) {
//loopContinue = false;
reject(`done`);
}
setTimeout(() => {
resolve('ok');
}, 1000);
});
}
必要に応じて、ループは5番目の反復後に中断します。 'loopContinue'グローバルは、仕事関数またはプロミスのキャッチ(または当時)に設定できます。 thenまたはcatchで 'break'を使用するだけで疲れましたが、エラーが発生します。
DoWorkで実行する場合は、キャッチを削除してdoWork()を呼び出し、doWorkの// loopContinue = falseのコメントを外します。どちらの方法でも機能します。これはnode.jsでテストされました
NextTickで何かを見つけましたが、これははるかに簡単に思えます。
はい。最初の例は、非同期条件でwhileループを使用する良い方法ですがgetBar
およびgetBar3
は非同期関数です(非同期としてマークされるか、単にPromise
を返します)。
もちろん実行は非同期コンテキスト内(async
関数内)である必要があります
私が見ることができる可能な問題は、最初にgetBar
が2回実行され、同じi
と残りの実行では、i
とwhile
の間で一致しないif
を使用します。 これが望ましい動作でない場合おそらくより正しいバージョンは次のようになります:
(async ()=>{
while(await getBar(i)) {
if (await getBar3(i)) {
//do something
}
i++;
}
})();
偽の例を見る here