为什么 Javascript SetTimeout() 不是多线程的

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12187393/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 15:32:09  来源:igfitidea点击:

why Javascript SetTimeout() is not multithreaded

javascript

提问by zb'

I have a test:

我有一个测试:

Html:

网址:

<div id="f1">Empty</div>
<div id="f2">Empty</div>

?

js:

js:

var s1 = function() {
? ??for (i = 1; i < 1000000000; i++) {
? ? ? ??var b = i * i;
? ??}
? ??$('#f1').html('Set');
}

var s2 = function() {
? ??if ($('#f1').html() == 'Empty') {
? ? ? ??$('#f2').html('Multi Thread');
? ? ? ??return;? ? ? ? ? ??
? ??};
? ??$('#f2').html('One Thread');
}

setTimeout(s2,110);
setTimeout(s1,100);?

is there any real reason why setTimeOut() not run in different threads, instead like event model ?

setTimeOut() 不是在不同线程中运行,而是像事件模型一样,有什么真正的原因吗?

jsfiddle

提琴手

回答by DVK

Javascript is not multithreaded nor non-multithreaded per se. However, the specific implementations of Javascript that currently are implemented in major browsers mostly ARE single-threaded.

Javascript 本身既不是多线程的,也不是非多线程的。但是目前各大浏览器中实现的Javascript的具体实现大多是单线程的。

In addition, for proper multithreading, the language needs to have facilities for shared memory, locks, semaphors and other concurrent programming tools, which JavaScript as is currently defined does not have (for example, there is no way to describe how concurrent JS threads would control who gets to update DOM objects that are of course, shared since there's only one DOM in a window).

此外,为了适当的多线程,语言需要有共享内存、锁、信号量和其他并发编程工具的设施,而目前定义的 JavaScript 没有(例如,无法描述并发 JS 线程如何控制谁可以更新 DOM 对象,这些对象当然是共享的,因为窗口中只有一个 DOM)。

There are attempts to make JS more parallelized - look at web workers, Intel's River Trail, Google's HTML5 workand more.

有人企图让JS更并行-看网络工作者,英特尔的河足迹,谷歌的HTML5工作更多

回答by Norguard

eicto, setTimeoutdoesn't fire code when requested.
It queues code, inline, with ALL of the other code that comes before it, but it sets its place in line to be at minimumthe time requested.

eicto,在请求时setTimeout不会触发代码。 它将代码与在它之前的所有其他代码一起内联排队,但它将其排队位置设置为至少请求的时间。

Moreover, most browsers have hard limits for minimum timeouts.
If you request a 1ms timeout, chances are good that in most browsers, you're going to get your request back 10ms-15ms later.

此外,大多数浏览器对最小超时都有硬性限制。
如果您请求 1 毫秒超时,那么在大多数浏览器中很有可能会在 10 毫秒到 15 毫秒后收到您的请求。

All of the JS interaction with the DOM, and, in reality, pretty much everything a single page does, all happens on one thread, with certain exceptions for custom browser extensions, and a few new APIs (like webworkers).

所有 JS 与 DOM 的交互,以及实际上单个页面所做的几乎所有事情都发生在一个线程上,除了自定义浏览器扩展的某些例外,以及一些新的 API(如 webworkers)。

This is why large projects need to be considerate of everything else on the page, and why everything needs to be asynchronous.

这就是为什么大型项目需要考虑页面上的其他所有内容,以及为什么所有内容都需要异步。

Because setTimeoutisn't a sleepand it doesn't return on the exact microsecond that it was croned in for... ...it puts a callback on the event stack, for a time no earlier than what you specify.

因为setTimeoutis not asleep并且它不会在它被cron编辑的确切微秒上返回... ...它在事件堆栈上放置一个回调,时间不早于您指定的时间。

回答by jfriend00

Lots and lots of design decisions went into Javascript's implementation in a browser that assumed it had only single thread access to the browser DOM and to other global variables/properties. This makes programming with it a lot less likely to cause problems, but introduces some limitations that have to be dealt with.

许多设计决策都涉及到浏览器中 Javascript 的实现,假设它只有单线程访问浏览器 DOM 和其他全局变量/属性。这使得使用它进行编程不太可能导致问题,但引入了一些必须处理的限制。

The language itself is perfectly capable of being multi-threaded and we already see that in WebWorkers and in some server implementations of the language. But, any time you use multiple threads and try to read/write to variables or properties that are shared between multiple threads, one MUST use protective devices (like mutexes) to allow reliable access to those shared resources. That significantly complicates how to do this programming and Javascript in a browser decided NOT to require that level of understanding in order to program it reliably.

该语言本身完全有能力成为多线程,我们已经在 WebWorkers 和该语言的一些服务器实现中看到了这一点。但是,每当您使用多个线程并尝试读取/写入在多个线程之间共享的变量或属性时,必须使用保护设备(如互斥锁)以允许可靠地访问这些共享资源。这使得如何在浏览器中进行这种编程变得非常复杂,并且 Javascript 决定不需要这种水平的理解来可靠地对其进行编程。

For anyone who has done multi-threaded programming, it can be powerful, but it is very, very easy to introduce difficult to find bugs. Those who are responsible for Javascript in a browser decided that that level of difficulty and the resulting types of bugs should be avoided entirely.

对于做过多线程编程的人来说,它可以很强大,但是很容易引入难以发现的错误。那些在浏览器中负责 Javascript 的人决定应该完全避免这种难度级别和由此产生的错误类型。

Even now with WebWorkers, there are no shared resources between a WebWorker and the main javascript thread. The two must communicate via a message passing system which is a foolproof way of forcing safety. And, the consequence is that one cannot access the DOM from a WebWorker. Instead, if you want the DOM to be changed, you have to post a message to the single main thread and ask IT to update the DOM. The main thread will recieve that message only when it's done doing other things (it's single threaded).

即使现在有了 WebWorker,WebWorker 和主 javascript 线程之间也没有共享资源。两者必须通过消息传递系统进行通信,这是一种确保安全的万无一失的方式。并且,结果是无法从 WebWorker 访问 DOM。相反,如果您希望更改 DOM,则必须向单个主线程发布消息并要求 IT 更新 DOM。主线程只有在完成其他事情时才会收到该消息(它是单线程的)。

It is also likely that the DOM has now spent a zillion years as a structure that is only designed for single threaded access so it would be a gigantic task to design and implement a way to access it from multiple threads (and fix all the resuling bugs in that implementation).

也很可能 DOM 现在已经作为一个专为单线程访问而设计的结构已经花费了无数年的时间,因此设计和实现一种从多线程访问它的方法(并修复所有由此产生的错误)将是一项艰巨的任务在那个实现中)。

回答by Aghilas Yakoub

Javascript don't support multithreading because the your interpreter in the browser is a single thread

Javascript 不支持多线程,因为浏览器中的解释器是单线程

回答by austincheney

JavaScript is not multithreaded, but even if it were setTimeout is a synchronous. setTimeout and setInterval are supplied by browsers outside of the proper JavaScript language, which provides an external means of access to the language, like event execution. When people refer to JavaScript as an asynchronous or multithreaded language this is likely what they are referring to because multiple external access points, such as numerous timers or event executions, can occur simultaneously each spawning a unique access point to the interpreter in memory. This is exactly what the developers of Node.js are referring to when they make such claims about JavaScript.

JavaScript 不是多线程的,但即使是 setTimeout 也是同步的。setTimeout 和 setInterval 由正确的 JavaScript 语言之外的浏览器提供,这提供了访问该语言的外部方式,例如事件执行。当人们将 JavaScript 称为异步或多线程语言时,这很可能是他们所指的,因为多个外部访问点,例如多个计时器或事件执行,可以同时发生,每个访问点都会为内存中的解释器生成一个唯一的访问点。这正是 Node.js 的开发人员在对 JavaScript 做出此类声明时所指的内容。

This means of multiple external access to various isolated threads can cause collisions in the UI, because a simulated multithreaded effect will likely cause collisions in browser output where there is only a single document object representing the entirety of a page. This is why setInterval with a short interval is generally deemed unsafe. setInterval is entirely asynchronous and will execute according to the interval provided even if execution in the prior interval has not concluded. This kind of collision is what I call fallover because the next interval is executing code that is falling over the prior execution and if your code requires access to the DOM or uses closures you will likely have problems. For safety a recursive setTimeout is recommended, because it is synchronous and the next round of execution will not occur until the prior has completed.

这种对各种隔离线程的多次外部访问可能会导致 UI 中的冲突,因为模拟的多线程效果可能会导致浏览器输出中的冲突,其中只有一个文档对象代表整个页面。这就是为什么通常认为间隔较短的 setInterval 是不安全的。setInterval 是完全异步的,即使前一个间隔中的执行尚未结束,也会根据提供的间隔执行。这种冲突就是我所说的失败,因为下一个时间间隔正在执行的代码与之前的执行失败,如果您的代码需要访问 DOM 或使用闭包,您可能会遇到问题。为了安全起见,建议使用递归 setTimeout,

回答by einpoklum

Mozilla does support multi-threading in Javascript - as long as you don't want to do UI work from multiple threads. The early versions of my Remove Duplicate Messages (Alternatve)exentsion were multi-threaded.

Mozilla 确实支持 Javascript 中的多线程 - 只要您不想从多个线程进行 UI 工作。我的Remove Duplicate Messages (Alternatve)扩展的早期版本是多线程的。

See my own bug pageregarding this issue in my extension, or better still, this pageabout using worker threads in Mozilla. eicto, you could very well implement your code using a background thread.

在我的扩展中查看我自己的关于这个问题的错误页面,或者更好的是,这个关于在 Mozilla 中使用工作线程的页面。eicto,您可以使用后台线程很好地实现您的代码。

回答by Richard Heath

Javascript is not multi threaded.

Javascript 不是多线程的。

HTML5 will give javascript multithread capabilities.

HTML5 将提供 javascript 多线程功能。

回答by Anand A.S

After waiting for the given amount of time, The execution for the methods (s1, s2) still happen in the javascript thread itself (which is single threaded).

在等待给定的时间后,方法 (s1, s2) 的执行仍然发生在 javascript 线程本身(它是单线程的)。

The reason why s2 waits for s1.

s2 等待 s1 的原因。