Good day, I'm working on a small JS loop that executes an action each X second-s randomly selected in a range, here is my current script:
var test = {
lastFrame: 0,
timeBeforeSomething: 0.0,
update: function() {
let now = Date.now();
if( this.lastFrame != undefined ) {
let delta = ( now - this.lastFrame ) / 1000;
if( this.timeBeforeSomething <= 0 ) {
this.doSomething();
this.timeBeforeSomething = Math.round( ( ( Math.random() * ( 1.0 - 0.5 ) ) + 0.5 ) * 1000 ) / 1000;
console.log( 'this.timeBeforeSomething = ' + this.timeBeforeSomething );
} else {
this.timeBeforeSomething -= delta;
console.log( 'this.timeBeforeSomething -= ' + delta + ' => ' + this.timeBeforeSomething );
}
}
this.lastFrame = now;
setTimeout( test.update, 0 );
},
doSomething: function() {
console.log( 'something' );
}
}
test.update();
My problem is coming from the timeBeforeSomething
attribute, indeed this-one is set to NaN at the second loop.
But I only: assign to it float values, and decrement value, so I don't understand why.
Here is a trace of what this script does print:
something
this.timeBeforeSomething = 0.672
this.timeBeforeSomething -= 0.01 => NaN
this.timeBeforeSomething -= 0.004 => NaN
this.timeBeforeSomething -= 0.012 => NaN
this.timeBeforeSomething -= 0.013 => NaN
this.timeBeforeSomething -= 0.015 => NaN
And from there, timeBeforeSomething
stay equal to 0.672, do you know why?
You need to bind your call to test.update
to the current this
context. Otherwise it will get the function's this
context in which timeBeforeSomething
is undefined:
setTimeout(test.update.bind(this), 1000);
Complete snippet:
var test = {
lastFrame: 0,
timeBeforeSomething: 0.0,
update: function() {
let now = Date.now();
if (this.lastFrame != undefined) {
let delta = (now - this.lastFrame) / 1000;
if (this.timeBeforeSomething <= 0) {
this.doSomething();
this.timeBeforeSomething = Math.round(((Math.random() * (1.0 - 0.5)) + 0.5) * 1000) / 1000;
console.log('this.timeBeforeSomething = ' + this.timeBeforeSomething);
} else {
this.timeBeforeSomething -= delta;
console.log('this.timeBeforeSomething -= ' + delta + ' => ' + this.timeBeforeSomething);
}
}
this.lastFrame = now;
setTimeout(test.update.bind(this), 1000);
},
doSomething: function() {
console.log('something');
}
}
test.update();