Javascript 在for循环中等待setTimeout可以吗?

Javascript 在for循环中等待setTimeout可以吗?,javascript,node.js,for-loop,async-await,settimeout,Javascript,Node.js,For Loop,Async Await,Settimeout,在Async/Await之前,当我们需要每隔X秒进行一次循环N时,我们可以选择使用for循环来包装settimeout,或者在setinterval周围使用包装器来计算执行并清除它的次数 但是使用async await可以这样做: async function newFashion() { for (let i = 0; i < 10; i++) { console.log(i); await sleep(1000); } console.log("Finish

Async/Await
之前,当我们需要每隔X秒进行一次循环N时,我们可以选择使用for循环来包装
settimeout
,或者在
setinterval
周围使用包装器来计算执行并清除它的次数

但是使用async await可以这样做:

async function newFashion() {
  for (let i = 0; i < 10; i++) {
    console.log(i);
    await sleep(1000);
  }
  console.log("Finish"); 
}
newFashion(); // 0 1 2 3 4 5 6 7 8 9 Finish

function oldFashion() {
  for (let i = 0; i < 10; i++) {
    setTimeout(() => {
      console.log(i);
    }, i * 1000);
  }
  console.log("Finish");
}
oldFashion(); // Finish 0 1 2 3 4 5 6 7 8 9

function sleep(time) {
  return new Promise((resolve) => { 
    setTimeout(resolve, time);
  });
}
异步函数newFashion(){ for(设i=0;i<10;i++){ 控制台日志(i); 等待睡眠(1000); } 控制台日志(“完成”); } newFashion();//01 2 3 4 5 6 7 8 9完成 函数oldFashion(){ for(设i=0;i<10;i++){ 设置超时(()=>{ 控制台日志(i); },i*1000); } 控制台日志(“完成”); } oldFashion();//完成0 1 2 3 4 5 6 7 8 9 功能睡眠(时间){ 返回新承诺((解析)=>{ setTimeout(解析,时间); }); } 我知道这两个人的行为不一样
oldFashion()
实际上并不在循环中“暂停”,而是在迭代时实际调用10
setTimeout()
,因此基本上他用10
setTimeout()
填充事件循环

newFashion()
不管它的行为如何,当他点击wait时,他会“停止”迭代,但我不确定它到底是如何工作的

那么,用N
setTimeout()
填充事件循环,或者一个接一个地等待,还有什么更好呢?在
newFashion()中实际发生了什么

编辑:更具体地说,每种方法在性能方面的收益是什么?当N很小时?当N很大时

在newFashion()中实际发生了什么

wait
表达式导致对
newFashion
函数的调用暂停,直到
sleep
函数的结果(承诺)被解决或拒绝。解析或拒绝后,它将继续代码的其余部分

那么,用N setTimeout()填充事件循环,或者 一个接一个地等待


如您所见,
async/await
部分更具可读性。如果环境支持
ES8
,您可以自由使用它
async/await
也是熟悉的程序员之一,他们是从C#等语言进入Javascript的,C#也使用
async/await
进行异步编程。对于他们来说,使用
async/await
比使用
for loop
示例更方便。

这里有一个编写“老式”版本的更好方法。它保留了让
“Finish”
日志排在最后的期望行为,并且不依赖于在将来的不同时间间隔立即设置一系列计时器

整个事情都是自足和清晰的

函数betterOldFashion(i,n){
if(ibetterOldFashion(0,10)我不相信你的新代码有任何问题,我个人觉得它更容易阅读。我个人更喜欢
constdelay=time=>newpromise(res=>setTimeout(res,time));)@科迪格。哈哈,我们这里要简单一点;)旧方法的可读性较差,部分原因是新方法将一部分工作转移到单独的功能中。而且,旧方法不会非常准确。首先,我不会使用
for
循环,如果您更感兴趣,它实际上不会在拒绝承诺后继续执行代码<代码>等待
如果其操作数承诺被拒绝,则抛出拒绝的原因。然后,抛出将拒绝调用
async
函数返回的承诺,除非它在try/catch块中被捕获。@traktor53您是对的。但无论如何,控件都会返回到
async
函数。它可以处理错误或通过调用堆栈抛出错误。第二个代码段真的很可怕。太脆弱了…@Bergi:它基本上和OP的代码一样,正如我所说,这是不可取的。我只是重新设计了这个解决方案,以显示通过将代码移出函数而获得的可读性差异,这就是OP对异步/等待版本所做的。