Reputation: 83
I am having trouble with Javascript async call. The Car class below has a move function which takes two arguments, the first one is a value, the second one is a call back function, which will be called after 1 second, and this callback function takes the value returned by forward method.
var Car = function() {
this._count = 0;
};
Car.prototype = {
move: function(value, onMoved) {
setTimeout(function() {
onMoved(this.forward(value));
}.bind(this), 1000);
},
forward: function(value) {
this._count = this._count + value;
return this._count;
}
};
I want to call the move function like this:
var values = [1, 2, 3, 4];
var car = new Car();
values.forEach(function(value) {
car.move(value, function(result) {
console.log(result);
});
});
Now my problem is the call back function onMoved does not wait for 1 second to execute between each value that it is outputting. How can I make it so it wait between each value that it is outputting? I am allowed to use underscore.js. Thanks.
Upvotes: 0
Views: 258
Reputation: 5115
Since you want a 1 sec. wait between each call, you might consider using the setInterval
method on window, instead of utilizing the setTimeout method:
You could add some method performing some actions for each iteration, and finish iterating when all values are processed:
var i=0;
function go(result) {
if (!!values[i]) {
car.move(values[i], function(result) {console.log(result);})
i++;
} else {
window.clearInterval(interval);
}
}
And call this function using setInterval
var interval = window.setInterval(go, 1000);
Have a look at the following fiddle:
https://jsfiddle.net/adw1k98m/1/
(see console log for output)
Upvotes: 0
Reputation: 801
setTimeout in javascript registers callback function in a queue to execute in future once the current execution stack is free. for example:-
while(1){
setTimeout(function(){
console.log('hello');
},1000);
}
this will not print hello as the execution stack will never be free.
Coming back to the example we call move method which will be pushed to a queue. After one second it starts executing each function one by one without any delay as the setTimeout is set to a fixed time ie. 1000 millisecond.
workaround:-
var Car = function() {
this._count = 0;
};
Car.statCount = 0;
Car.prototype = {
move: function(value, onMoved) {
this.constructor.statCount++;
setTimeout(function() {
onMoved(this.forward(value));
}.bind(this), 1000*Car.statCount);
},
forward: function(value) {
this._count = this._count + value;
return this._count;
},
constructor: Car
};
var values = [1, 2, 3, 4];
var car = new Car();
values.forEach(function(value) {
car.move(value, function(result) {
console.log(result);
});
});
Upvotes: 1