While 循环使用 Await Async。

Posted

技术标签:

【中文标题】While 循环使用 Await Async。【英文标题】:While loops using 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# 所做的)。 “正确的方法”是什么意思?如果此代码符合您的要求,那么它是正确的。 我无法尽可能多地测试它,它在我对它应该做什么的解释中按预期工作,但不确定这是否不仅仅是运气。 【参考方案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 上找到了一些东西,但这似乎更容易。

【讨论】:

以上是关于While 循环使用 Await Async。的主要内容,如果未能解决你的问题,请参考以下文章

5 种在循环中使用 async/await 的方法,建议收藏

Dart:在循环中使用 Async 和 Await

JS255- 如何在 JS 循环中正确使用 async 与 await

C# async 和 await 理解

async/await 会阻塞事件循环吗? [复制]

当循环在异步函数内部而不是相反时,为啥 Async/Await 可以正常工作?