JavaScript:同时运行两个循环

5

我是javascript和node.js的新手,

这里有两个循环,我想让它们同时运行。

function loop1(){
    for (var i = 10000; i < 20000; i++) {
        console.log(i);
    }
}
function loop2(){
    for (var i = 0; i < 10000; i++) {
        console.log(i);
    }
}
loop1();
loop2();

这意味着我期望的输出结果是这样的。
10000
0
10001
1
...
19999
9999

但是这个输出结果为

10000
10001
...
19999
0
1
...
9999

我曾尝试使用Promise,例如:

Promise.all([loop1(), loop2()])

但是什么也没发生。

对此有什么想法吗?我的最终目标是将文件夹中的文件分成两半并并行处理它们。因此,多线程或多进程可能是可接受的。感谢您的帮助。


这个回答解决了你的问题吗?JavaScript能同时运行多个函数吗? - Md Sabbir Alam
如果使用console.log(i); console.log(i - 10000);,您将获得所需的结果,但我不认为这会对此有所帮助。即使JavaScript适合处理多个文件,我也不确定您希望通过同时处理多个文件来获得什么收益。 - user5734311
1
我阅读了这篇文章并尝试使用Promise.all([loop1(),loop2()]),但它并没有像我预期的那样工作。它只是分别运行两个循环。 - maxcsh
5个回答

5

只有异步函数*可以异步执行**(无需工作线程)

async function loop1(){
    for (var i = 10000; i < 20000; i++) {
        await console.log(i);
    }
}
async function loop2(){
    for (var i = 0; i < 10000; i++) {
        await console.log(i);
    }
}
loop1();
loop2();

*异步函数:包括那些在内部使用事件/定时器/承诺(可选地)并返回Promise的函数。
**其中包含await的函数。

3

很好的问题。

JS是单线程的,这意味着它不能并行运行。对于一个异步语言来说,像JS一样顺序运行所有内容可能有些奇怪,但基本上就是这样发生的。

然而,JS通过事件循环将工作分成任务和微任务的方式提供了并行工作的“假象”。关于事件循环还有很多要讲的,我建议观看Jake Archibald的这个演讲,但是基本上你的函数loop1是同步的,不会被拆分为任务,因此在执行其他操作之前,它将完成运行。

你无法使loop1loop2并行运行,但是你可以将它们拆分为微任务,以便它们像这样执行

t=0 loop1's microtask 1
t=1 loop2's microtask 1
t=2 loop1's microtask 2
t=3 loop2's microtask 2
...

一个简单的方法是在每次迭代中使用await。 这将创建一个异步的promise,尽快解决,并在此期间将控制流返回给其他等待任务或微任务。
这就是为什么会先运行loop1然后是loop2

const loop1 = () => {
  for (let i = 0; i < 5; i++) {
    console.log(i);
  }
}
const loop2 = () => {
  for (let i = 5; i < 10; i++) {
    console.log(i);
  }
}
loop1();
loop2();

但这将同时运行 loop1 loop2

const loop1 = async () => {
  for (let i = 0; i < 5; i++) {
    console.log(i);
    
    // defer the remaining work to another microtask
    // gives back control to awaiting microtasks, like loop2's remaining work
    await null;
  }
}
const loop2 = async () => {
  for (let i = 5; i < 10; i++) {
    console.log(i);
    
    // defer the remaining work to another microtask
    // gives back control to awaiting microtasks, like loop1's remaining work
    await null;
  }
}
loop1();
loop2();


2
对于并行工作,您可以在浏览器中使用 JavaScript 的 Web Workers,在 Node.js 中使用 worker threads
此外,您还可以使用 setTimeout,但它不会真正地并行执行,它只是告诉 JavaScript 稍后运行。

function loop1(){
    for (let i = 100; i < 200; i++) {
        setTimeout(() => console.log(i));
    }
}
function loop2(){
    for (let i = 0; i < 100; i++) {
        setTimeout(() => console.log(i));
    }
}

loop1();
loop2();


你应该使用let来使你的代码工作。 - apple apple
我认为使用工作线程可能是解决这个问题的另一个选项。让我看看文档。谢谢。 - maxcsh

1
使用 promises.all() 进行并行运行
function loop1(){
      return new  Promise((resolve, reject) =>{
        for (var i = 10000; i < 20000; i++) {
          console.log('loop1 =>', i);
        }
        resolve();
      })
    }
    
    function loop2(){
      return new Promise((resolve, reject) =>{
      for (var i = 0; i < 10000; i++) {
        console.log('loop2 =>', i);
      }
     
      resolve();
    });
    }
    
    Promise.all([loop1(), loop2()]);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接