关于javascript:异步编程是否意味着多线程?

Does async programming mean multi-threading?

让我们来谈谈每一秒都有setInterval方法的javascript代码。

我也有一个onblur动画事件来控制。

onblur发生的情况下(+animation),我可能得到setInterval函数。

所以我的问题是:异步编程是否意味着多线程?(无论如何?)

我知道javascript不是多线程语言。

那么……?


不,它的字面意思是异步的。了解异步编程和基于线程的编程之间的区别对于您作为程序员的成功至关重要。

在传统的非线程环境中,当函数必须等待外部事件(如网络事件、键盘或鼠标事件,甚至时钟事件)时,程序必须等待直到该事件发生。

在多线程环境中,许多单独的编程线程同时运行。(根据CPU的数量和操作系统的支持,这可能是事实,也可能是复杂的调度算法造成的幻觉)。因此,多线程环境很困难,并且涉及线程锁定彼此的内存以防止它们相互溢出的问题。

在非同步环境中,单个进程线程一直运行,但由于事件驱动的原因(这是关键),它可能从一个函数切换到另一个函数。当一个事件发生时,当当前运行的进程到达它必须等待另一个事件的点时,javascript核心然后扫描它的事件列表,并以(正式的)不确定(但可能是确定的)顺序将下一个事件传递给事件管理器。

因此,事件驱动的异步编程避免了传统多线程编程的许多陷阱,例如内存争用问题。可能仍然存在竞争条件,因为事件处理的顺序不是由您决定的,但它们是罕见的,而且更容易管理。另一方面,由于事件处理程序在当前运行的函数到达空闲点之前不会传递事件,因此某些函数可能会使其余的编程变得匮乏。例如,在node.js中会发生这种情况,当人们愚蠢地在服务器中进行大量繁重的计算时——最好将其放入该节点的一个小服务器中,然后"等待"以提供答案。对于事件来说,node.js是一个很好的小型交换台,但是任何超过100毫秒的事件都应该以客户机/服务器的方式处理。

在浏览器环境中,dom事件被视为自动事件点(它们必须是,修改dom会传递很多事件),但即使是写得不好的javascript也会使内核挨饿,这就是为什么firefox和chrome都有这些"这个脚本已停止响应"中断的原因。处理程序。


单线程事件循环是单线程语言中异步的一个很好的例子。

这里的概念是将doLater回调处理程序附加到eventLoop上。那么,eventLoop只是一个while(true)来检查每个doLater处理程序的特定时间戳是否满足,如果满足,它就会调用该处理程序。

对于那些感兴趣的人来说,这里有一个简单的(非常低效的玩具)JavaScript单线程事件循环的实现。

这意味着,如果没有任何类型的OS线程调度程序访问您的单线程,您就不得不忙着等待doLater回调。

如果你有一个sleep调用,你可以直接执行sleep直到下一个doLater处理程序,这比一个繁忙的等待更有效,因为你重新安排了你的单线程并让操作系统做其他事情。


只有在这样的意义上,它才随意地执行代码,并冒着竞争条件的风险。使用超时和间隔不会获得任何性能优势。

但是,HTML5的WebWorkers的确允许在浏览器中进行真正的多线程处理:http://www.html5rocks.com/en/tutorials/workers/basics/


如果有一个回调,必须调用它。执行单元是线程,因此,是的,其他一些线程必须直接调用回调,或者通过排队对启动线程进行异步过程调用来调用回调。