socket.io里面的socket.io不起作用

时间:2015-06-17 17:20:21

标签: node.js

我试图在循环内发出事件。但是,只需启动第一个事件(开始)和一次。

控制台中的行为必须是: 一个 发出事件开始 发出事件结束 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);

1 个答案:

答案 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 - 现在您了解此网站自己的徽标。它是一个调用堆栈:)