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

why Javascript SetTimeout() is not multithreaded

本文关键字:多线程 Javascript SetTimeout 为什么      更新时间:2023-09-26

我有一个测试:

Html:

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

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);​

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

jsfiddle

Javascript本身既不是多线程的,也不是非多线程的。然而,目前在主要浏览器中实现的Javascript的具体实现大多是单线程的。

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

有人试图让JS更加并行化——看看网络工作者、英特尔的River Trail、谷歌的HTML5等等。

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

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

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

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

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

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

此外,大多数浏览器对最小超时都有严格的限制
如果你请求1ms的超时,在大多数浏览器中,你很可能会在10ms-15ms后收到请求。

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

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

因为setTimeout不是sleep,它不会在cron输入的精确微秒上返回。。。…它在事件堆栈上放置一个回调,时间不早于您指定的时间。

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

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

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

Javascript不是多线程的。

HTML5将提供javascript多线程功能。

Mozilla确实支持Javascript中的多线程,只要你不想从多个线程中进行UI工作。早期版本的删除重复消息(Alternatve)执行是多线程的。

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

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

s2等待s1的原因。