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