首页 > 解决方案 > javascript中的异步编程是什么意思?

问题描述

这个循环大约需要 1.5 秒。

console.time("test")
for (let i = 0; i < 1000000000; i++) {}
console.timeEnd("test")

我的问题是...

setTimeout(() => {
  for (let i = 0; i < 1000000000; i++) {}
  console.log("banana");
}, 2000);

setTimeout(() => {
  for (let i = 0; i < 1000000000; i++) {}
  console.log("apple");
}, 2000);

setTimeout(() => {
  for (let i = 0; i < 1000000000; i++) {}
  console.log("mango");
}, 2000);


console.log("finished")

每个 setTimeOut() 需要 2 秒,但每个战利品需要 1.5 秒。
所以我应该得到

finished!
// 2 secs later
banana 
apple 
mango (all at once)

但输出是

finished
// 2s later
 banana
  // 1.5s later
 apple
  // 1.5s later
 mango

标签: javascriptasynchronous

解决方案


您应该观看此视频https://www.youtube.com/watch?v=8aGhZQkoFbQ,它详细解释了问题/行为。

简而言之:setTimeout 会将所有循环放在“事件回调”队列中。当现在延迟已经过去时,它将一个接一个地执行循环并执行它们。但是由于一个循环需要 1.5 秒才能运行,所以这 1.5 秒会阻止其他一切运行,因为在 JS 中,所有代码(不包括 Web api)都将在主事件循环中执行:

Programm start: 
loop1 => gets put into Event Callqueue (takes some milliseconds)
loop2 => gets put into Event Callqueue (takes some milliseconds)
loop3 => gets put into Event Callqueue (takes some milliseconds)
finalized is outputted. 

after 2000 milliseconds (as set in setTimout): 
loop1 => gets taken from queue and executed in the main event loop = takes 1,5 senconds and this blocks everything!
loop2 => the same... takes 1,5 seconds to execute 
loop3 => the same... takes 1,5 seconds to execute 

JS 只能为某些特殊的外部 API “并行”执行代码。大多数代码在主事件循环中按顺序执行!理解这个概念绝对重要。

如果您正在寻找“Javascript 中的线程”,那么Webworkers可能是一个非常好的替代方案/解决方案。它们允许在后台并行执行 JS。


推荐阅读