我试图在循环内发出事件。但是,只需启动第一个事件(开始)和一次。
控制台中的行为必须是: 一个 发出事件开始 发出事件结束 b 发出事件开始 发出事件完成
又一次
一 发出事件开始 发出事件结束 b 发出事件开始 发出事件完成
但是,它的行为方式如下:
一 发出事件开始 B'/ P>
又一次
一 B'/ P>
为什么事件只发出一次?
var server = require('http').createServer();
var io = require('socket.io')(server);
var sleep = require('sleep');
io.on('connection', function(socket){
socket.on('disconnect', function(){});
});
server.listen(3000);
function B() {
this.bundles = ['a', 'b'];
this.currentPosition = 0;
this.run = function() {
var bundle = this.bundles[this.currentPosition];
console.log(bundle);
io.emit('start', { 'bundle': bundle });
io.emit('finish', { 'bundle': bundle });
++this.currentPosition;
if (this.bundles[this.currentPosition] === undefined) {
this.currentPosition = 0;
}
sleep.sleep(2);
this.run();
}
}
//wait to start server
setTimeout(function(){
var b = new B();
b.run();
}, 6000);
答案 0 :(得分:3)
尝试将其更改为setInterval
。
http://codepen.io/Chevex/pen/zGdQXQ
this.run = function() {
var bundle = this.bundles[this.currentPosition];
console.log(bundle);
io.emit('start', { 'bundle': bundle });
io.emit('finish', { 'bundle': bundle });
++this.currentPosition;
if (this.bundles[this.currentPosition] === undefined) {
this.currentPosition = 0;
}
}
setInterval(this.run.bind(this), 2000);
间隔将每2秒运行一次并且不会使您的调用堆栈泛滥。
每当从另一个函数调用函数时,都会构建一个调用堆栈。
function foo() {
bar();
}
function bar() {
console.log('end of stack, returning');
}
foo();
上面的代码将构建一个这样的堆栈:
-> event loop
-> foo
-> bar
-> console.log
然后当函数开始返回时,它们逐个弹出堆栈。这意味着当你从内部调用一个函数时,如果递归调用永远不会停止,你肯定会耗尽调用堆栈。
function foo() {
foo();
}
foo();
这会导致一个丑陋的调用堆栈,会让你的记忆变干。
-> event loop
-> foo
-> foo
-> foo
-> foo
-> foo
-> etc...
您可以看到JavaScript引擎甚至会尝试检测何时发生这种情况并抛出异常。如果递归堆栈更复杂,引擎并不总是捕获这些。最好避免它并坚持setInterval
。
通过使用setInterval
,您可以向节点注册一个函数,并在每次经过一定的毫秒数时告诉它触发它。这会保存您的调用堆栈,因为该函数被触发,返回,然后在节点事件循环检测到再次经过n
毫秒时再次启动。没有无限的调用堆栈会导致...
... Stack Overflow
PS - 现在您了解此网站自己的徽标。它是一个调用堆栈:)