这个 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 循环的方法吗?
谢谢!!
在异步条件下使用 while 循环是正确的方法吗?
是的。
async function
s 只是在每个 await
暂停执行,直到各自的承诺履行,并且任何控制结构继续像以前一样工作。
是的,这样做很好:
let stopped = false
// infinite loop
while(!stopped) {
let res = await fetch('api link')
if (res.something) stopped = true // stop when you want
}
在异步条件下使用 while 循环是正确的方法吗?
是,前提是
getBar
和getBar3
是异步函数(标记为async或者只是返回一个Promise
)。
当然执行应该在异步上下文中(在
async
函数中)
一个可能的issue,我可以看到,最初有 2 次执行
getBar
具有相同的 i
,其余执行使用 i
和 while
之间不匹配的 if
。 如果这不是期望的行为也许更正确的版本是:
(async ()=>{
while(await getBar(i)) {
if (await getBar3(i)) {
//do something
}
i++;
}
})();
看一个模拟的例子在这里
// returns a delayed promise
const delay = ms => new Promise(resolve => setTimeout(resolve, ms))
// performs a specific (mathematical) operation every "ms" (milliseconds)
const dec = async (i, ms) => (await delay(ms), --i)
const foo = async () => {
let i = 5;
// runs an async operation which decreases "i" by 1 every 500ms
while(i = await dec(i, 500))
// prints 4, 3, 2, 1 with a delay
console.log(i)
}
foo()
这是我的GIST如果你需要给它加星标以备后用。
// returns a delayed promise
const delay = ms => new Promise(resolve => setTimeout(resolve, ms))
// performs a specific (mathematical) operation every "ms" (miliseconds)
const inc = async (i, ms) => (await delay(ms), ++i)
const foo = async () => {
let i = 0;
// runs an async operation which increases "i" by 1 every 500ms
while((i = await inc(i, 500)) < 5) {
// prints 1,2,3,4 with a delay
console.log(i)
}
}
foo()
基于这个例子,我们看到在
await
循环中使用while
会触发SYNCHRONOUS代码执行。换句话说,在循环的一次迭代完成之前,不会开始第二次循环
let counter = 0;
const promise = () =>
new Promise((resolve, reject) =>
setTimeout(() => {
resolve(1);
}, 2000)
);
(async() => {
console.log("Start")
console.time('allTime');
while (counter < 3) {
await promise();
console.log('Resolve promise', counter);
counter++;
}
console.timeEnd('allTime');
})();
由于
while
循环体同步工作,我们需要将代码移出循环体。while(await (async () => {
Boo = await getBar3(i)
if (Boo) {
// something
}
Foo = await getBar(i)
i++
return Foo; // you must return the condition that the loop depends on it
})()); // Adding this semicolon is crucial
问这个问题已经有一段时间了。在使用其他语言多年(从穿孔卡和纸带开始)之后,我是 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 可以在 work 函数中设置,也可以在 promise 的 catch(或者可以是 then)中设置。我厌倦了在 then 或 catch 中使用“break”,但出现错误。
如果你想在 doWork 中这样做,你可以消除 catch 并调用 doWork() 并取消注释 doWork 中的 // loopContinue= false。无论哪种方式都有效。这是用 node.js 测试的
我在 nextTick 上找到了东西,但这似乎容易多了。