2012-08-29 11 views
6

En mi código, tengo una serie de llamadas a funciones. Repaso estas llamadas y uso .apply() para llamarlas. El problema es que si la llamada de la nueva función requiere algún tipo de tiempo, el ciclo aplicará .apply() y llamará a la siguiente función antes de que se complete la función anterior. >. < Aquí se muestra un ejemplo:¿Cómo puedo agregar una devolución de llamada al método .apply()?

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

Así que si hubo una devolución de llamada de la función de aplicar a continuación, esto podría funcionar como quiero que lo haga. es decir,

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

También tengo una pregunta acerca de cómo llamar a someFunc dentro de una función de devolución de llamada. Las funciones en mi matriz calls afectan mi variable element. Así que quiero asegurarme de que después de que se modifique se pase a algún Funk en la devolución de llamada para que la siguiente función pueda manipularlo también. A veces me confundo con el contexto this. :)

Si ayuda, estoy usando jQuery. Sé cómo agregar devoluciones de llamada a los métodos de jQuery, pero no sé cómo hacerlo cuando trato con el código JavaScript nativo. ¿Cómo puedo agregar una devolución de llamada al método .apply()?

+1

No hay forma de hacer lo que desea a menos que conozca un patrón de parámetros que siga todas sus funciones. – Pointy

+0

@Pointy - ¿Por qué necesitaría un patrón de parámetros si pongo todos mis parámetros en una matriz alias 'args'? – Aust

+0

El problema es que no hay forma de saber si una función es asincrónica y está diseñada para aceptar un parámetro de función de devolución de llamada (o dos de esos parámetros, o más). No puede hacer que el sistema "espere" una función y su seguimiento asincrónico finalice. Por lo tanto, si * sabe * que todas sus funciones (por ejemplo) toman una devolución de llamada como el último parámetro, entonces podría resolver algo. – Pointy

Respuesta

2

Asegúrese de que cada función a la que llama devuelva promise. A continuación, puede "esperar" a que prometen ser "resuelto" antes de continuar con la siguiente función en su lista:

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); 
     }); 
    } 
} 

con cada función buscando algo como:

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(); 
} 

Si la tarea asíncrona es una llamada AJAX puede simplemente devolver el resultado jqXHR de $.ajax directamente en lugar de crear un nuevo objeto diferido.

+0

Si algunas de las funciones que paso a mi variable 'calls' no son mías, ¿cómo agregaría' $.Objeto diferido() '? ¿Podría envolverlo en otra función, o eso es posible? – Aust

+0

Sí, podría ajustar las funciones, pero _de alguna manera_ todavía tiene que 'resolver' la promesa y eso tiene que hacerse en la devolución de llamada asíncrona. – Alnitak

+0

Entonces, incluso si lo envolví, ¿vuelvo al problema original que planteó @Pointy? ¿Cuál es, si una función no tiene una devolución de llamada, entonces lo que quiero es imposible? – Aust

Cuestiones relacionadas