Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I add a callback to the .apply() method?

In my code, I have an array of function calls. I loop over these calls and use .apply() to call them. The problem is that if the call of the new function takes any sort of time, the loop will .apply() and call the next function before the prior function is finished. >.< Here is an example:

function someFunc(element, calls){
  if(calls.length){
    fn = calls[0];
    calls.shift();
    fn.apply(element, args);
    someFunc(element, calls);
  }
}

So if there was a callback on the apply function then this could work how I want it to. i.e.

function someFunc(element, calls){
  if(calls.length){
    fn = calls[0];
    calls.shift();
    fn.apply(element, args, function(){
      someFunc(element, calls);
    });
  }
}

I also have a question about calling someFunc inside of a callback function. The functions in my calls array affect my element variable. So I want to make sure after it gets changed that it gets passed to someFunc in the callback so the next function can manipulate it as well. Sometimes I just get confused with the this context. :)

If it helps, I am using jQuery. I know how to add callbacks to jQuery methods but I don't know how to do that when I'm dealing with native JavaScript code. How can I add a callback to the .apply() method?

like image 577
Aust Avatar asked Aug 29 '12 18:08

Aust


1 Answers

Make sure that every function you call returns a promise. You can then "wait" for that promise to be "resolved" before continuing with the next function in your list:

function someFunc(element, calls) {
    if (calls.length) {
        var fn = calls.shift();
        fn.apply(element, args).done(function(el) {  // what's args?
            el = el || element;   // default to previous element if necessary
            someFunc(el, calls);
        });
    }
}

with each function looking something like:

function myFunc1(el) {
    var def = $.Deferred();

    // do something async, and "resolve" the deferred object in the async callback
    ...(function() {
        def.resolve(el);  // this "el" will get passed to the next function
    });

    return def.promise();
}

If the asynchronous task is an AJAX call you can just return the jqXHR result of $.ajax directly instead of creating a new deferred object.

like image 102
Alnitak Avatar answered Sep 28 '22 09:09

Alnitak