2012-08-29 10 views
6

Nel mio codice, ho una serie di chiamate di funzione. Faccio un giro su queste chiamate e uso .apply() per chiamarle. Il problema è che se la chiamata della nuova funzione richiede un certo periodo di tempo, il ciclo eseguirà .apply() e chiamerà la funzione successiva prima che la funzione precedente sia terminata. >. < Ecco un esempio:Come posso aggiungere una richiamata al metodo .apply()?

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

Quindi, se ci fosse un callback sulla funzione di applicare allora questo potrebbe funzionare come voglio io. Ad esempio

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

Ho anche una domanda su come chiamare un po 'Func all'interno di una funzione di callback. Le funzioni nell'array calls influiscono sulla mia variabile element. Quindi voglio essere sicuro che dopo averlo cambiato, venga passato a someFunc nel callback in modo che anche la prossima funzione possa manipolarlo. A volte mi confondo con il contesto this. :)

Se aiuta, sto usando jQuery. So come aggiungere i callback ai metodi jQuery ma non so come farlo quando ho a che fare con il codice JavaScript nativo. Come posso aggiungere una richiamata al metodo .apply()?

+1

Non c'è modo di fare ciò che si vuole se non si conosce un modello parametro che tutte le funzioni seguono. – Pointy

+0

@Pointy - Perché dovrei avere bisogno di un pattern di parametri se metto tutti i miei parametri in una matrice alias 'args'? – Aust

+0

Il problema è che non è possibile stabilire se una funzione è asincrona e progettata per accettare un parametro della funzione callback (o due di questi parametri o più). Non è possibile fare in modo che il sistema "aspetti" una funzione e il suo follow-on asincrono termini. Quindi, se * sai * che tutte le tue funzioni (ad esempio) prendono una richiamata come ultimo parametro, allora potresti risolvere qualcosa. – Pointy

risposta

2

assicurarsi che ogni funzione chiamata restituisce un promise. È possibile quindi "aspettare" per che promettono di essere "risolto" prima di continuare con la prossima funzione nella vostra 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 ciascuna funzione che assomiglia a:

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

Se l'operazione asincrona è un AJAX chiamata si può semplicemente restituire il risultato di jqXHR$.ajax direttamente invece di creare un nuovo oggetto differita.

+0

Se alcune delle funzioni che ho inserito nella mia variabile 'calls' non sono mie, come aggiungerei' $.Deferred() 'oggetto? Potrei avvolgerlo in un'altra funzione, o è anche possibile? – Aust

+0

Sì, è possibile eseguire il wrap delle funzioni, ma in alcuni casi è necessario "risolvere" la promessa e ciò deve essere eseguito nel callback asincrono. – Alnitak

+0

Quindi, anche se l'ho avvolto, torno al problema originale sollevato da @Pointy? Qual è, se una funzione non ha già una richiamata, quindi quello che voglio è impossibile? – Aust

Problemi correlati