JavaScript - 事件驱动和并发问题?

8

您好,

我一直在学习JavaScript和Node.js。但是我不明白JavaScript如何避免并发问题。

假设我正在处理一个对象,

var bigObject = new BigObject();

我有一个 setTimer(function(){ workOnBigOjbect...} ),它也会在 bigOjbect 上工作。

如果我正在将磁盘IO写入 bigObject,并且一个定时器对象正在处理 bigObject,以及定期从 bigObject 读取的代码,如何避免并发问题?

在普通语言中,我会使用互斥锁或线程安全的队列/命令模式。我也没有看到关于JavaScript竞争条件的讨论。

我有什么遗漏吗?

4个回答

9
整个node.js的关键在于它是事件驱动的。所有代码都在单线程的事件处理程序中运行。由于代码不会并发运行,所以没有并发问题。缺点是每个事件处理程序必须快速退出,因为它会阻塞其他事件。
在您的示例中,代码将启动磁盘IO并立即退出。Node.js基础设施将通过运行事件处理程序来通知程序IO操作已完成。计时器事件将在IO事件之前或之后调用,但永远不会同时发生。

4
“咯吱、咯吱” 转动齿轮的声音在我的脑海中响起!我明白了,但我需要再沉淀一下。 - Daniel
1
最好的理解方式是使用它——在node.js中编写几个小程序。 - Amnon
@Daniel,你是不是想说冥想? :) 另外,我觉得我刚才在脑海中听到了同样的声音。我要在语言和平台之间来回多少次,才会让我的大脑崩溃呢? - snapfractalpop

3

Javascript是单线程的。如果根据您调用setTimer的方式,函数应该执行的时间到了,而父代码仍在运行,则函数将在父代码完成后才执行。


2

只有一个线程;参见:Node.js在多核机器上的应用

我猜测这是因为底层的V8 JavaScript引擎不支持多线程,因为通常JavaScript在浏览器中执行(在Windows情况下只有单个UI线程),并且不支持多线程。


这实际上是一个设计决策:进程是Node.js的基本单位。无论如何,JavaScript是一种事件驱动的语言,因此线程并没有太多意义。 - xj9

1

在JavaScript中有一个叫做Run-to-Completion的东西,它确保代码在执行时完全执行,然后才运行任何其他(异步)代码,因此没有并发问题。

在您的示例中,无论何时调用计时器回调,它都将完全执行,并且永远不会在执行其他代码的中间被抢占。

有关更多详细信息,请参见为什么JavaScript中没有并发控制工具


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接