Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 当事件循环阻止应用程序执行I/O操作时?_Javascript - Fatal编程技术网

Javascript 当事件循环阻止应用程序执行I/O操作时?

Javascript 当事件循环阻止应用程序执行I/O操作时?,javascript,Javascript,我刚刚读了一篇关于JavaScript中事件循环的文章。 我发现了两个矛盾的短语,如果有人能澄清,我会很高兴 这种模式的一个缺点是,如果一条消息花费太长的时间 完成后,web应用程序无法处理用户交互 如单击或滚动。浏览器通过“一个脚本正在运行”来缓解这种情况 “运行时间太长”对话框 事件循环模型的一个非常有趣的特性是 与许多其他语言不同,JavaScript从不阻塞。处理 I/O通常通过事件和回调执行,因此 应用程序正在等待IndexedDB查询返回或XHR 请求返回时,它仍然可以处理其他事情,

我刚刚读了一篇关于JavaScript中事件循环的文章。 我发现了两个矛盾的短语,如果有人能澄清,我会很高兴

这种模式的一个缺点是,如果一条消息花费太长的时间 完成后,web应用程序无法处理用户交互 如单击或滚动。浏览器通过“一个脚本正在运行”来缓解这种情况 “运行时间太长”对话框

事件循环模型的一个非常有趣的特性是 与许多其他语言不同,JavaScript从不阻塞。处理 I/O通常通过事件和回调执行,因此 应用程序正在等待IndexedDB查询返回或XHR 请求返回时,它仍然可以处理其他事情,如用户输入

那么,第一个什么时候是真的,第二个什么时候是真的

“事件循环模型的一个非常有趣的特性是 与许多其他语言不同,JavaScript从不阻塞

这是有误导性的。如果没有巧妙的编程,JavaScript总是会阻止UI线程,因为运行时逻辑总是设计成阻止UI。以每秒60帧的速度,这意味着应用程序逻辑必须始终协同产生控制(或简单地完成执行)在大约16毫秒内,否则您的UI将冻结或结巴

正因为如此,大多数可能需要很长时间的JavaScript API(例如网络请求)都是以这样一种方式设计的,即使用技术(例如回调、承诺)来规避此问题,这样它们就不会阻塞事件循环,从而避免UI变得无响应


换句话说:主机环境(如Web浏览器或Node.js运行时实例)专门设计用于支持使用基于事件的编程模型(最初受Mac上Hypercard等编程环境的启发),从而可以要求主机环境执行长时间运行的任务(如运行计时器),而不会阻塞执行的主线程,并在长时间运行的任务完成后通过“事件”通知您的程序,使您的程序能够从停止的地方重新开始。

两者都是正确的,尽管我同意它的表达有点错误

因此,按点数:

  • 确实,如果同步任务需要很长时间才能完成,那么事件循环“卡在”那里,然后所有其他排队的任务在完成之前都无法运行

  • 这里讨论的是异步任务,因此,即使HTTP请求、I/O请求或任何异步任务需要很长时间才能处理,所有同步任务都可以继续完成它们的工作,比如处理用户输入


  • Javascript中有两种类型的代码

  • 同步(就像一个接一个地进行)
  • 异步(就像跳转到未来一样)
  • 同步代码 如果您希望使用同步代码查找1到10000000之间的素数,您将编写一个函数,该函数将执行计算并查找给定范围内的素数,但同步代码会发生什么情况。在该任务完成之前,javascript引擎无法执行任何任务


    异步代码 如果您将相同的代码封装在回调中,或者更友好地使用SetTimeout方法,javascript会将该函数放入事件队列中,并在某个特定时间到来时执行其他操作。当调用堆栈中没有任何内容时,timeout方法会触发回调,它会要求事件循环传递第一个内容,即inside事件队列。因此,这更多地是关于寻找空闲时间来执行繁重的操作

    使用javascript工作者执行繁重的数学任务,而不是 SetTimeout,因为最终,当 函数位于调用堆栈中

    在解释Javascript中异步的含义/作用时,前两行是必须的。+1