让我们谈谈每秒钟都有setInterval
方法的JavaScript 代码2
。
我还有一个onblur
用于某些控件的动画事件。
在onblur
发生(+动画)的情况下,我可能会得到该setInterval
功能。
所以我的问题是:
异步编程是否意味着多线程?(以任何方式?)
我知道 Javascript 不是多线程语言。
所以...?
让我们谈谈每秒钟都有setInterval
方法的JavaScript 代码2
。
我还有一个onblur
用于某些控件的动画事件。
在onblur
发生(+动画)的情况下,我可能会得到该setInterval
功能。
所以我的问题是:
异步编程是否意味着多线程?(以任何方式?)
我知道 Javascript 不是多线程语言。
所以...?
不。它的字面意思是它的意思 - 异步。了解异步编程和基于线程的编程之间的区别对于您作为程序员的成功至关重要。
在传统的非线程环境中,当函数必须等待外部事件(例如网络事件、键盘或鼠标事件,甚至时钟事件)时,程序必须等到该事件发生。
在多线程环境中,许多单独的编程线程同时运行。(根据 CPU 的数量和操作系统的支持,这可能是真的,也可能是由复杂的调度算法造成的错觉)。由于这个原因,多线程环境很困难,并且涉及线程锁定彼此的内存以防止它们彼此溢出的问题。
在异步环境中,单个进程线程一直运行,但出于事件驱动的原因(这是关键),它可能会从一个功能切换到另一个功能。当一个事件发生时,当当前运行的进程到达一个必须等待另一个事件的点时,javascript 核心然后扫描它的事件列表并以(正式)不确定(但可能是确定性的)顺序传递下一个事件, 给活动经理。
因此,事件驱动的异步编程避免了传统多线程编程的许多缺陷,例如内存争用问题。可能仍然存在竞争条件,因为处理事件的顺序不取决于您,但它们很少见且更易于管理。另一方面,由于事件处理程序在当前运行的函数到达空闲位置之前不会传递事件,因此某些函数可能会使其余的编程变得饥饿。例如,这发生在 Node.js 中,当人们愚蠢地在服务器中进行大量繁重的数学运算时 - 最好将其推入一个小服务器,该节点然后“等待”提供答案。Node.js 是一个很棒的小型事件交换机,但是任何需要超过 100 毫秒的时间都应该以客户端/服务器的方式处理。
在浏览器环境中,DOM 事件被视为自动事件点(它们必须是,修改 DOM 会传递很多事件),但即使是写得不好的 Javascript 也会使核心饿死,这就是为什么 Firefox 和 Chrome 都有这些“此脚本已停止响应”中断处理程序。
单线程事件循环是单线程语言中异步的一个很好的例子。
这里的概念是将doLater
回调处理程序附加到eventLoop
. 然后eventLoop
它只是while(true)
检查是否满足每个doLater
处理程序的特定时间戳,如果满足则调用处理程序。
对于那些感兴趣的人,这里是JavaScript 中单线程事件循环的一个幼稚(而且效率极低的玩具)实现
这确实意味着如果没有任何类型的操作系统线程调度程序访问您的单个线程,您将被迫忙于等待doLater
回调。
如果您有sleep
电话,您可以sleep
在下一个doLater
更高效的处理程序之前执行此操作,因为您取消了单线程的调度并让操作系统执行其他操作,因此您需要进行繁忙的等待。
只是在它随意执行代码并冒着竞争条件的风险的意义上。使用超时和间隔不会获得任何性能优势。
然而,HTML5 的 WebWorkers 确实允许在浏览器中实现真正的多线程:http : //www.html5rocks.com/en/tutorials/workers/basics/
没有异步编程并不特别意味着多线程。
为了同时实现多个任务,我们使用多线程,其他是 node js 中的事件循环架构。
JavaScript 是同步的和单线程的,这就是为什么 node js 也是单线程的,但使用事件循环 node 执行非阻塞 I/O 操作。Node.js 使用 libuv 库,该库使用固定大小的线程池来处理并行任务的执行。
线程是一系列代码指令,也是进程的子单元。
在多线程中,进程有多个线程。在单线程中,进程具有单线程。
如果有回调,则必须调用它。执行单位是线程,所以,是的,其他一些线程必须直接调用回调,或者通过将一些异步过程调用排队到启动线程来调用回调。