Loourr
Loourr

Reputation: 5125

writing a function queue in javascript

I have an object which can only place 60 API calls per minute. So what I would like to do, is when a function call comes that I know I wont be allowed to place, add it to a queue, and call the function again at a more convenient time.

Heres how I thought to fix it

var API_caller = function(){
    this.function_queue = [];
};

API_caller.prototype.make_api_call = function(){
    if(this.can_make_call()){
        this.make_call();
    } else {
        // If I cant place an API call then add 
        // the function to the function queue
        this.function_queue.push(this.make_api_call);       
    }
};

API_caller.prototype.queue_call = function(){
    // remove function from queue and call it
    var func = this.function_queue.shift();
    func();
}

This works fine for functions without parameters but what if make_api_call() had a parameter

API_caller.prototype.make_api_call = function(data){
    if(this.can_make_call()){
        this.make_call();
    } else {
        // If I cant place an API call then add 
        // the function to the function queue
        this.function_queue.push(this.make_api_call(data));     
    }
};

In this case however, make_api_call(data) will be evaluated before it is pushed to function_queue and func will no longer hold a function causing queue_call() to error.

How can I get around this?

Upvotes: 0

Views: 349

Answers (3)

Xion
Xion

Reputation: 22770

You can queue up an ad-hoc function that contains your API call with the argument already bound:

var that = this;
this.function_queue.push(function() {
    that.make_api_call(data);
));

The aliasing of this to that is required, because inside the anonymous function, this would not be bound to the same object as outside.

Note this technique is similar to eclanrs' answer, but doesn't rely on bind method's availability.

Upvotes: 0

elclanrs
elclanrs

Reputation: 94101

You can partially apply arguments to a function with bind:

this.function_queue.push(this.make_api_call.bind(this, data));

Check MDN for support in old browsers.

Upvotes: 1

HBP
HBP

Reputation: 16033

The queue entry should contain the function, f and the parameters as an array, p.

When you add to the queue you would do something like queue.push ([f, arguments]) and when the time comes to make that call it would be something like queue[0][0].apply (null, queue[0][1])

Upvotes: 0

Related Questions