给出这段代码:
while(true){
...
}
这可以异步执行多少次?
我已经写了这个以测试它与Google's JavaScript V8 Engine的交互方式,并且一次只有一个while循环活动。
var cycles = 0;
var counter = new Date();
var OpsStore = [];
var threads = [];
for(var i = 0; i < 10; i++){
setTimeout(newThread(i),0);
}
function renew(){
if (secondPassed(counter, new Date())){
counter = new Date();
Ops();
}
cycles++;
}
function newThread(id){
threads.push({id: id, active: true});
return function(){
while(true){
console.log(id);
threads[id].active = true;
renew();
}
}
}
function Ops(){
OpsStore.push(cycles);
console.log(cycles, ' avg: ', getAvgOps());
console.log(threads);
cycles = 0;
for(var i = 0; i < threads.length; i++){
threads[i].active = false;
}
}
function secondPassed(d1, d2){
return ((d2 - d1) >= 1000);
}
function getAvgOps(){
var sum = 0;
for (var i = 0; i < OpsStore.length; i++){
sum += OpsStore[i];
}
return sum / OpsStore.length;
}
结果:
4147371 ' avg: ' 4147371
[ { id: 0, active: true },
{ id: 1, active: true },
{ id: 2, active: true },
{ id: 3, active: true },
{ id: 4, active: true },
{ id: 5, active: true },
{ id: 6, active: true },
{ id: 7, active: true },
{ id: 8, active: true },
{ id: 9, active: true } ]
4071504 ' avg: ' 4109437.5
[ { id: 0, active: true },
{ id: 1, active: false },
{ id: 2, active: false },
{ id: 3, active: false },
{ id: 4, active: false },
{ id: 5, active: false },
{ id: 6, active: false },
{ id: 7, active: false },
{ id: 8, active: false },
{ id: 9, active: false } ]
出于教育目的,是否有可能有多个while循环在JavaScript中不断迭代?
答案 0 :(得分:5)
我认为你遗漏了javascript如何工作的基本内容。 Javascript是单线程的。有关详细信息,请参阅MDN文档中的此参考: MDN Docs
触发事件后,事件回调将执行直至完成。在此期间发生的任何事件都将被推送到事件队列。一旦当前执行完成,它将从事件队列开始下一个。
这种行为的原因是因为第一个会继续执行直到完成,然后第二个事件才会开始执行。
答案 1 :(得分:1)
接受这只是一个实验,你可以调查generators/iterators以允许一个&#34;循环&#34;屈服,允许下一个运行。然而,正如妖精已经在他的回答中所说,真正的并发性超出了单个JS引擎。
David Walsh撰写了good tutorial on generators。
请注意,这些是在ES6中定义的,现在是not implemented natively in all browsers,但它们有polyfill / shims。这是我发现的random blog post。
答案 2 :(得分:1)
简短回答:不,你不能同时运行几个while循环。正如其他人所说,Javascript是单线程的,只有在主线程上没有运行时才会在事件循环上执行事件。因为你的while循环永远不会结束,所以它永远不会将控件返回给javascript引擎。
但是,您可以使用递归无限地交替执行多个函数(或直到事件队列变得饥饿)
你可以做这样的事情
var threads = [];
for(var i = 0; i < 10; i++){
setTimeout(newThread(i),0);
}
function newThread(id){
threads.push({id: id, active: true});
console.log(id);
threads[id].active = true;
return function(){
setTimeout(newThread(id),0)
}
}