2012-08-29 13 views
6

W moim kodzie mam tablicę wywołań funkcji. Pętli przez te połączenia i użyj .apply(), aby je wywołać. Problem polega na tym, że jeśli wywołanie nowej funkcji trwa jakiś czas, pętla będzie .apply() i wywoła następną funkcję przed zakończeniem poprzedniej funkcji. >. < Oto przykład:Jak dodać wywołanie zwrotne do metody .apply()?

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

Więc jeśli nie było funkcji oddzwaniania na zastosowanie to może działać jak chcę go. tj.

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

Mam również pytanie o wywołanie funkcji SomeFunc wewnątrz funkcji wywołania zwrotnego. Funkcje w mojej macierzy calls wpływają na moją zmienną element. Dlatego chcę się upewnić, że po zmianie zostanie ona przekazana do funkcji SomeFunc w wywołaniu zwrotnym, aby następna funkcja mogła również nią manipulować. Czasami po prostu mylę się z kontekstem this. :)

Jeśli to pomaga, używam jQuery. Wiem, jak dodać wywołania zwrotne do metod jQuery, ale nie wiem jak to zrobić, gdy mam do czynienia z natywnym kodem JavaScript. Jak dodać wywołanie zwrotne do metody .apply()?

+1

Nie ma sposobu, aby zrobić to, co chcesz, o ile nie znasz wzorca parametrów, za którym odpowiadają wszystkie twoje funkcje. – Pointy

+0

@Pointy - Dlaczego miałbym potrzebować wzorca parametru, jeśli umieściłbym wszystkie moje parametry w tablicy aka 'args'? – Aust

+0

Problem polega na tym, że nie można określić, czy dana funkcja jest asynchroniczna i ma akceptować parametr funkcji zwrotnej (lub dwa takie parametry lub więcej). Nie można sprawić, aby system "czekał" na funkcję, a jej asynchroniczna kontynuacja zakończy się. Tak więc, jeśli * wiesz *, że wszystkie twoje funkcje (na przykład) przyjmują wywołanie zwrotne jako ostatni parametr, możesz coś wymyślić. – Pointy

Odpowiedz

2

Upewnij się, że każda funkcja, którą wywołujesz, zwraca promise. Można wtedy „czekać” na tej obietnicy, aby być „rozwiązany” przed przejściem do następnej funkcji na liście:

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

z każdej funkcji poszukuje coś takiego:

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

Jeśli asynchroniczny zadaniem jest wywołanie AJAX można po prostu bezpośrednio zwrócić wynik jqXHR z $.ajax zamiast tworzenia nowego obiektu odroczonego.

+0

Jeśli niektóre funkcje, które przekazuję do mojej zmiennej 'calls' nie są moje, w jaki sposób mogę dodać' $.Odroczony() obiekt? Czy mogę zawinąć to w inną funkcję, czy jest to nawet możliwe? – Aust

+0

Tak, możesz owijać funkcje, ale _ponieważ nadal musisz "rozwiązać" obietnicę i to musi być wykonane w asynchronicznym wywołaniu zwrotnym. – Alnitak

+0

Więc nawet jeśli go zapakowałem, wracam do pierwotnego problemu, który przyniosła @Pointy? Co oznacza, że ​​jeśli funkcja nie ma jeszcze wywołania zwrotnego, to, czego chcę, jest niemożliwe? – Aust

Powiązane problemy