2016-08-23 115 views
5

這個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...}  
     } 
    } 
    } 
}) 

如果你能表現出另一種方式與異步做到這一點伺機+ while循環,這是完全錯誤的?

謝謝!

+0

只是FYI,異步/等待不是ES 6的一部分。 –

+0

等待轉換成狀態機。你可以像你寫的那樣擁有許多小型狀態機(很難推理),或者你可以有一個更大的狀態機(這就是C#所做的)。 –

+0

「正確的方式」是什麼意思?如果這個代碼做你想要的,那麼它是正確的。 –

回答

8

這是正確的方式來使用while循環與異步條件?

是的。 async function只需在每個await之前暫停執行,直到相應的承諾完成,並且任何控制結構繼續像以前一樣工作。

0

自問這個問題以來,它已經有一段時間了。我是多年來從事其他語言(從打孔卡和紙帶開始)並且需要解決此問題的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'global可以在工作函數中設置,也可以在承諾的catch(或可能是then)中設置。我厭倦了在當時使用'休息'或抓住,但我得到一個錯誤。

如果你想在doWork中做到這一點,你可以消除catch並且只需調用doWork()並取消doWork中// loopContinue = false的註釋。無論哪種方式工作。這與node.js測試

我發現了nextTick上的東西,但這似乎更容易。