如果用户断开连接或符合条件,停止方法/间隔

如果用户断开连接或符合条件,停止方法/间隔

问题描述:

我想创建一个客户可以查看其订单状态的实时订购页面。如果用户断开连接或符合条件,停止方法/间隔

因此,我想每10秒运行一个函数,检查SQL数据库,如果订单已准备就绪。

function checkOrder(socket, userid, checkinterval) { 



    pool.getConnection(function(err, connection) { 
     // Use the connection 
     connection.query('SELECT * FROM orders WHERE user = ' + userid + ' ORDER BY timestamp DESC', function(err, rows) { 

      var alldone = false; 
      for (var i = 0; i < rows.length; i++) { 
       if (rows[i]['status'] == 'completed') { 
        alldone = true; 
       } else { 
        alldone = false; 
        break; 
       } 
      } 

      socket.emit('order-update', rows); 
      connection.release(); 

      if (alldone) { 
       console.log('all done'); 
       socket.emit('execute', '$("#orderstatus").html(\'Done\');'); 
       clearInterval(checkinterval); 

      } 


     }); 
    }); 



} 

var express = require('express'); 

var app = express(); 
var app = express(); 
var options = { 
    key: fs.readFileSync('privkey.pem'), 
    cert: fs.readFileSync('cert.pem'), 
    ca: fs.readFileSync("chain.pem") 
}; 
var server = require('https').createServer(options, app); 

var io = require('socket.io')(server); 

var port = 443; 

server.listen(port, function() { 

    console.log('Server listening at port %d', port); 

}); 


io.on('connection', function(socket) { 

    socket.on('trackorder', function(userid) { 
     var checkinterval = setInterval(function() { 
      checkOrder(socket, userid, checkinterval); 
     }, 10000); 
    }); 

    socket.on('disconnect', function() { 


     clearInterval(checkinterval); 


    }); 

}); 

现在我遇到了停止该功能的问题,如果任务完成或客户端断开连接。

我怎么能做到这一点?我想clearInterval()将在函数内部工作,因为它已通过,但on disconnect事件处理程序存在问题。 checkinterval未定义,或者如果我在全局定义它,它会停止错误的功能。

这怎么能正确完成?

+1

简单地说,不要使用间隔来处理异步内容。如果这会延迟很多并发请求的运行。只需使用递归setTimeout –

disconnect事件发生时,您的checkInterval变量超出范围。您需要将其定义提升到一个水平。

io.on('connection', function(socket) { 
    // checkInterval variable is declared at this scope so all event handlers can access it 
    var checkInterval; 
    socket.on('trackorder', function(userid) { 
     // make sure we never overwrite a checkInterval that is running 
     clearInterval(checkInterval); 
     checkInterval = setInterval(function() { 
      checkOrder(socket, userid, checkInterval); 
     }, 10000); 
    }); 

    socket.on('disconnect', function() { 
     clearInterval(checkinterval); 
    }); 
}); 

另外:

  1. 我加了一个防范覆盖checkInterval变量,如果你有机会的trackorder事件不止一次相同的客户端。

  2. 你在一个地方拼错了checkinterval

  3. 正如其他人所说,代表每个客户端轮询您的数据库是一个坏的设计,不会扩展。你需要使用数据库触发器(所以它会告诉你什么时候某些有趣的事情发生了变化),或者让你自己的代码对数据库进行相关的更改会触发更改。不要代表每个客户进行投票。

  4. 您在pool.getConnection()connection.query()中没有错误处理。

而不是那复杂的setInterval的东西,只是添加一个小的IIFE,如果结果尚未在那里调用自己。一些伪代码:

function checkOrder(socket, userid){ 
//a variable pointing to the running timer 
var timer; 
//on error clear 
socket.on("disconnect",()=>clearTimout(timer)); 
//a small IIFE 
(function retry(){ 
    pool.getConnection(function(err, connection) { 
    //parse & notice socket 
    if (!alldone) //retry 
     timer = setTimeout(retry, 1000); 
    }); 
})(); 
} 
+0

在这种情况下,如果用户断开连接,我将如何停止检查? – maddo7

我会说你使用了一种不好的方法。你应该去而不是

我的意思是,当订单状态改变时发出事件。不要让数据库的负担无缘无故地频繁发生。

上的成功地位的变化,发出事件order_status_updateorder id,什么是new status

socket.emit('order_status_update', {order_id: 57, status: 'In Process'}); 

这样,你不需要任何形式的循环或setInterval的等别担心,即使客户端连接的或不,其sockat.io业务来照顾它。你只会提出这个事件。