user2914136
user2914136

Reputation: 83

Javascript async call

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

Answers (2)

Philip Bijker
Philip Bijker

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

abs
abs

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

Related Questions