I have the following code:
var mmanager = require("./mmanager");
var { spawn } = require("child_process");
var exports = {
interval: {},
setup: function (n){
if(n){
this.n = n;
}
},
continuous_scan: function (){
console.log("Setting intervals");
this.interval = setInterval(this.get_connections,120000); //120000 ms
console.log("Interval:",this.interval);
this.get_connections();
},
get_connections: function (){
if(this.n){
let py = spawn("python3",["get_connections.py"]);
let dataString = '';
py.stdout.on("data", (data) => {
dataString += data;
});
py.stdout.on("end",() => {
var response = JSON.parse(dataString);
if(this.scan){
this.last_scan = this.scan;
}
this.scan = response;
let obj = {
data: response,
n: this.n
}
mmanager.insert(obj,function(err,res){
if(err){
console.log("Error inserting data");
return;
}
console.log(res);
if(this.interval){ //some debug to see what happens
console.log(this.interval);
}else{
console.log("interval not found");
}
return;
});
});
console.log("Start capturing ("+this.n+") ...");
py.stdin.write(JSON.stringify(this.n));
py.stdin.end();
}
},
stop_scan: function (){
if(this.interval){
this.interval.clearInterval();
return true;
}else{
return false;
}
}
}
module.exports = exports;
What i want to do is to execute this python3 script every 2 minutes and insert the data in a database. When i run this code i get the first execution of the code but it seems to fail in the others.
I've also seen that the interval is not found in the execution of get_connections
.
The output:
Setting intervals
Interval: Timeout {
_called: false,
_idleTimeout: 120000,
_idlePrev:
TimersList {
_idleNext: [Circular],
_idlePrev: [Circular],
_timer: Timer { '0': [Function: listOnTimeout], _list: [Circular] },
_unrefed: false,
msecs: 120000,
nextTick: false },
_idleNext:
TimersList {
_idleNext: [Circular],
_idlePrev: [Circular],
_timer: Timer { '0': [Function: listOnTimeout], _list: [Circular] },
_unrefed: false,
msecs: 120000,
nextTick: false },
_idleStart: 336,
_onTimeout: [Function: get_connections],
_timerArgs: undefined,
_repeat: 120000,
_destroyed: false,
[Symbol(asyncId)]: 6,
[Symbol(triggerAsyncId)]: 1 }
Start capturing (2) ...
{...
some successful result
...}
interval not found
And it does not follow after 2 minutes.
I don't know if the problem is in the assignation of the interval variable or in the async execution of node.js
How can I solve this?
When passing get_connection as callback to setInterval you loose the reference to you exports object and this
is not export but the global object.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
In most cases, the value of this is determined by how a function is called. It can't be set by assignment during execution, and it may be different each time the function is called. ES5 introduced the bind method to set the value of a function's this regardless of how it's called, and ES2015 introduced arrow functions which don't provide their own this binding (it retains the this value of the enclosing lexical context).
To get the right this you can either bind the function to the exports object or putting a closure around the function call.
this.interval = setInterval(() => this.get_connections(),120000); //120000 ms