我有一个测试:
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()不能在不同的线程中运行,而不是像事件模型一样?
答案 0 :(得分:16)
Javascript本身不是多线程的,也不是非多线程的。但是,目前在主流浏览器中实现的Javascript的具体实现大多是单线程的。
此外,对于正确的多线程,语言需要具有共享内存,锁,信号量和其他并发编程工具的工具,这些工具当前定义的JavaScript没有(例如,没有办法描述如何并发JS线程将控制谁更新DOM对象,这些对象当然是共享的,因为窗口中只有一个DOM。)
有人试图让JS更加并行化 - 看看网络工作者,英特尔的River Trail,Google's HTML5 work和more。
答案 1 :(得分:4)
许多设计决策都投入到Javascript在浏览器中的实现,该浏览器假设它只具有对浏览器DOM和其他全局变量/属性的单线程访问权限。这使得使用它进行编程的可能性不大,但会引入一些必须处理的限制。
语言本身完全能够实现多线程,我们已经在WebWorkers和该语言的某些服务器实现中看到了这一点。但是,每当您使用多个线程并尝试读取/写入多个线程之间共享的变量或属性时,必须使用保护设备(如互斥锁)来允许可靠地访问这些共享资源。这大大简化了如何进行编程和浏览器中的Javascript决定不需要那种理解水平以便可靠地编程。
对于已经完成多线程编程的人来说,它可以很强大,但是很容易引入很难找到的bug。那些在浏览器中负责Javascript的人决定应该完全避免这种难度和产生的错误类型。
即使现在使用WebWorkers,WebWorker和主要javascript线程之间也没有共享资源。两者必须通过消息传递系统进行通信,这是一种强制安全的万无一失的方式。而且,结果是无法从WebWorker访问DOM。相反,如果您希望更改DOM,则必须将消息发布到单个主线程并要求IT更新DOM。主线程只有在完成其他事情(它是单线程)时才会收到该消息。
DOM现在也可能花费了数十年的时间作为仅针对单线程访问而设计的结构,因此设计和实现从多个线程访问它的方法将是一项巨大的任务(并修复所有线程)该实施中的结果错误。)
答案 2 :(得分:4)
eicto,setTimeout
在请求时不会触发代码 。
它将代码(内联)与之前的所有其他代码排在一起,但它将其位置排列为 至少 所请求的时间。
此外,大多数浏览器都有最低超时的硬限制 如果你请求1毫秒超时,很可能在大多数浏览器中,你将在10毫秒到15毫秒之后收到你的请求。
所有JS与DOM的交互,实际上,几乎所有单个页面都做了,所有这些都发生在一个线程上,自定义浏览器扩展有一些例外,还有一些新的API(比如webworkers)。 / p>
这就是为什么大型项目需要考虑页面上的其他内容,以及为什么一切都需要异步。
因为setTimeout
不是sleep
,并且它没有返回cron
为{...}}的精确微秒。
...它在事件堆栈上放置一个回调,时间不早于你指定的时间。
答案 3 :(得分:2)
Javascript不支持多线程,因为浏览器中的解释器是单线程
答案 4 :(得分:1)
JavaScript不是多线程的,但即使它是setTimeout也是同步的。 setTimeout和setInterval由适当的JavaScript语言之外的浏览器提供,它提供了访问语言的外部方法,如事件执行。当人们将JavaScript称为异步或多线程语言时,这很可能是他们所指的,因为多个外部访问点(例如众多计时器或事件执行)可以同时发生,每个访问点都会在内存中生成一个唯一的解释器访问点。这正是Node.js的开发人员在提出有关JavaScript的声明时所指的。
这意味着对各种隔离线程的多次外部访问可能会导致UI中的冲突,因为模拟的多线程效果可能会导致浏览器输出中的冲突,其中只有一个文档对象表示整个页面。这就是为什么具有短间隔的setInterval通常被认为是不安全的。 setInterval是完全异步的,即使前一个区间中的执行尚未结束,也会根据提供的间隔执行。这种冲突就是我称之为失败转移,因为下一个时间间隔正在执行落在先前执行中的代码,如果您的代码需要访问DOM或使用闭包,则可能会遇到问题。为安全起见,建议使用递归setTimeout,因为它是同步的,并且在前一个完成之前不会发生下一轮执行。
答案 5 :(得分:0)
Javascript不是多线程的。
HTML5将提供javascript多线程功能。
答案 6 :(得分:0)
Mozilla确实支持Javascript中的多线程 - 只要您不想从多个线程执行UI工作。我的Remove Duplicate Messages (Alternatve) exentsion的早期版本是多线程的。
请参阅我的扩展程序中有关此问题的my own bug page,或者更好的是this page,了解如何在Mozilla中使用工作线程。 eicto,您可以使用后台线程很好地实现您的代码。
答案 7 :(得分:-1)
在等待了给定的时间后,方法(s1,s2)的执行仍会在javascript线程本身(单线程)中进行。
s2等待s1的原因。