让我们来谈谈每一秒都有setInterval方法的javascript代码。
我也有一个onblur动画事件来控制。
在onblur发生的情况下(+animation),我可能得到setInterval函数。
所以我的问题是:异步编程是否意味着多线程?(无论如何?)
我知道javascript不是多线程语言。
那么……?
- 不,异步性(ism?)不需要并行。
- 在封面下面有线程,但作为程序员/语言消费者,它不是。
- @杰森,封面下面没有线。或者至少没有必要。
- @杰森:封面下也不一定有多条线。
- 不是我不相信你,而是请引用。我假设不同的javascript运行时使用多线程来产生异步行为。
- 我读错了吗?看起来Mozilla JS引擎使用多个线程,我只能假设其他线程也使用多个线程:developer.mozilla.org/en/spidermonkey/jsapi-reference/jsrunt‌&8203;ime"一次只能有一个线程使用JSContext。"在一个JS线程安全构建中,多个线程可以在同一个JSRuntime中同时运行JavaScript代码,但每个这样的线程必须有自己的JSContext。"
- 你读错了。注意两个重要的警告:首先,您必须构建一个JS线程安全环境,即使这样,每个JSContext对象也只有一个线程。因此,JavaScript上下文的每个实例仍然是单线程的。这看起来更像每个tab/iframe处理一个线程,每个上下文。同时,V8引擎(Chrome背后的javascript)是完全单线程的,node.js对此做了大量工作:blog.mixu.net/2011/02/01/Understanding the node js event loo‌&8203;p
- .NET标记是意外添加的吗?.NET标记似乎与此问题无关(我在文章中没有看到任何.NET框架内容)。
不,它的字面意思是异步的。了解异步编程和基于线程的编程之间的区别对于您作为程序员的成功至关重要。
在传统的非线程环境中,当函数必须等待外部事件(如网络事件、键盘或鼠标事件,甚至时钟事件)时,程序必须等待直到该事件发生。
在多线程环境中,许多单独的编程线程同时运行。(根据CPU的数量和操作系统的支持,这可能是事实,也可能是复杂的调度算法造成的幻觉)。因此,多线程环境很困难,并且涉及线程锁定彼此的内存以防止它们相互溢出的问题。
在非同步环境中,单个进程线程一直运行,但由于事件驱动的原因(这是关键),它可能从一个函数切换到另一个函数。当一个事件发生时,当当前运行的进程到达它必须等待另一个事件的点时,javascript核心然后扫描它的事件列表,并以(正式的)不确定(但可能是确定的)顺序将下一个事件传递给事件管理器。
因此,事件驱动的异步编程避免了传统多线程编程的许多陷阱,例如内存争用问题。可能仍然存在竞争条件,因为事件处理的顺序不是由您决定的,但它们是罕见的,而且更容易管理。另一方面,由于事件处理程序在当前运行的函数到达空闲点之前不会传递事件,因此某些函数可能会使其余的编程变得匮乏。例如,在node.js中会发生这种情况,当人们愚蠢地在服务器中进行大量繁重的计算时——最好将其放入该节点的一个小服务器中,然后"等待"以提供答案。对于事件来说,node.js是一个很好的小型交换台,但是任何超过100毫秒的事件都应该以客户机/服务器的方式处理。
在浏览器环境中,dom事件被视为自动事件点(它们必须是,修改dom会传递很多事件),但即使是写得不好的javascript也会使内核挨饿,这就是为什么firefox和chrome都有这些"这个脚本已停止响应"中断的原因。处理程序。
- 关于jquery中的Ajax调用,服务器端代码做它的事情,而我的浏览器保持做其他功能……?
- 不过,这些不是线程。您已在浏览器端代码中向服务器发送了一条消息。当调用返回是一个事件时,您的代码将接收该事件并对其进行处理。当它等待时,EventLoop将处理其他事件。当事件返回时,EventLoop将对单个进程线程授予回调完全控制权,直到您通过到达回调的末尾、执行导致EventLoop进行的操作或创建新事件而放弃它为止。
- 一个很好的答案,感谢你以一种合理的无专业术语的方式解释这一点。
- 为什么"需要超过100毫秒的任何事情都应该以客户机/服务器的方式处理"?Ajax调用有时需要超过100毫秒,我的浏览器没有给我"这个脚本已经停止响应"的消息。
- trusktr:因为节点是单线程的,所以不应该使用处理请求的进程,也不应该执行大量的程序提升;不应该使用相同的进程来执行自然语言处理或图像处理;应该在子进程中执行该操作。每一个进程都需要时间;每一个其他进程都将被阻塞,直到完成为止。如果您在子进程中这样做,您可以释放"切换面板"进程来处理I/O。
- Ajax调用是客户端/服务器。
- 事件循环是第二个线程,尽管是在幕后——小个子正在监听事件。还是我在这里丢了什么?
单线程事件循环是单线程语言中异步的一个很好的例子。
这里的概念是将doLater回调处理程序附加到eventLoop上。那么,eventLoop只是一个while(true)来检查每个doLater处理程序的特定时间戳是否满足,如果满足,它就会调用该处理程序。
对于那些感兴趣的人来说,这里有一个简单的(非常低效的玩具)JavaScript单线程事件循环的实现。
这意味着,如果没有任何类型的OS线程调度程序访问您的单线程,您就不得不忙着等待doLater回调。
如果你有一个sleep调用,你可以直接执行sleep直到下一个doLater处理程序,这比一个繁忙的等待更有效,因为你重新安排了你的单线程并让操作系统做其他事情。
只有在这样的意义上,它才随意地执行代码,并冒着竞争条件的风险。使用超时和间隔不会获得任何性能优势。
但是,HTML5的WebWorkers的确允许在浏览器中进行真正的多线程处理:http://www.html5rocks.com/en/tutorials/workers/basics/
如果有一个回调,必须调用它。执行单元是线程,因此,是的,其他一些线程必须直接调用回调,或者通过排队对启动线程进行异步过程调用来调用回调。
- 同一个线程很可能稍后调用回调。
- @雷诺斯怎么办?如果一个线程直接调用一个函数,它就称为"调用"。如果在某个输入循环中将回调信号发送到线程中,则必须有某个对象将回调排队。驱动程序可以直接这样做,但它通常是内核线程。
- 通过让整个事件循环在单个线程中活动。请注意,线程那时不能执行任何IO,它只能与自身以及单个线程中的任何内容进行异步通信。这可能很迂腐。
- 这不是卖弄学问,雷诺斯。你说得对。它是一个执行线程,程序指针是一个单实例。学习可视化事件队列及其挂起的函数——学习尊重这一点,在事件驱动的编程中,函数不会返回到它停止的位置——是我理解node.js的最大的关键。
- 我认为我们都在从不同的角度争论同一点。在操作系统方面,必须有一些东西将事件加载到队列中。在这方面,"异步编程意味着多线程吗?"(在某种程度上)""答案必须是肯定的。从JS的角度来看,情况不同。
- 不,答案不一定是多线程的。不要混淆操作系统调度、程序员级线程和异步事件处理。那就是疯狂。
- @martinjames单线程事件循环
- 与此讨论相关:Mozilla JavaScript运行时现在正式是单线程的。