【问题标题】:While loops using Await Async.While 循环使用 Await Async。
【发布时间】:2016-12-30 20:21:34
【问题描述】:

这个 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 循环的方法?

谢谢!!

【问题讨论】:

  • 仅供参考,async/await 不是 ES 6 的一部分。
  • await 转换为状态机。您可以拥有许多已编写的小型状态机(很难推理),也可以拥有一个更大的状态机(例如 C# 所做的)。
  • “正确的方法”是什么意思?如果此代码符合您的要求,那么它是正确的。
  • 我无法尽可能多地测试它,它在我对它应该做什么的解释中按预期工作,但不确定这是否不仅仅是运气。

标签: loops asynchronous while-loop async-await ecmascript-next


【解决方案1】:

在异步条件下使用while循环是否正确?

是的。 async functions 只需在每个 await 上暂停它们的执行,直到各自的承诺实现,并且任何控制结构继续像以前一样工作。

【讨论】:

    【解决方案2】:

    是的,这样做很好:

    let stopped = false
            
    // infinite loop
    while(!stopped) {
        let res = await fetch('api link') 
        if (res.something) stopped = true // stop when you want
    }
    

    【讨论】:

      【解决方案3】:

      在异步条件下使用while循环是否正确?

      前提是 getBargetBar3 是异步函数(标记为异步或仅返回 Promise)。

      当然执行应该在异步上下文中(在async函数内)

      我可以看到的一个可能的问题是,最初有 2 次 getBar 使用相同的 i 执行,其余的执行使用 iwhile 之间不匹配的 i if如果这不是所需的行为,更正确的版本可能是:

          (async ()=>{
           while(await getBar(i)) {    
              if (await getBar3(i)) {
                //do something
              }
              i++;
            }
          })();
      

      查看模拟示例here

      【讨论】:

        【解决方案4】:

        这个问题被问到已经有一段时间了。经过多年的其他语言(从打孔卡和纸带开始),我是 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 可以设置在工作函数中,也可以设置在 promise 的 catch(或者可以是 then)中。我厌倦了在 then 或 catch 中使用“break”,但出现错误。

        如果您想在 doWork 中执行此操作,您可以消除捕获,只需调用 doWork() 并取消注释 // loopContinue= false 在 doWork 中。无论哪种方式都有效。这是用 node.js 测试的

        我在 nextTick 上找到了一些东西,但这似乎更容易。

        【讨论】:

          猜你喜欢
          • 2020-08-03
          • 2016-02-04
          • 2019-07-16
          • 1970-01-01
          • 2022-10-04
          • 2020-05-30
          • 1970-01-01
          • 1970-01-01
          • 2021-03-30
          相关资源
          最近更新 更多