wtorek, czerwca 19, 2007

Magia CallBacka w JavaScript :-) - czyli jak przekazać dodatkowy parametr

Czasem w JavaScript'cie istnieje konieczność przekazania funkcji, która zostanie później wywołana przez cudzy kod (tzw. callback). Funkcja taka ma często przyjmować jakiś parametr, tudzież parametry które zostaną do niej przekazane z obcego kodu.
Sytuację taką mamy np. w trakcie oprogramowywania obsługi zdarzenia onSuccess obiektu Ajax.Request w bibliotece Prototype.
Np. tak jak to jest w poniższym przykładzie.


var handlerFunc = function(t) {
alert(t.responseText);
}

var errFunc = function(t) {
alert('Error ' + t.status + ' -- ' + t.statusText);
}

var handlerFunc = function(t) {
var xmlDoc = t.responseXML.documentElement;
//Handle data.
}

new Ajax.Request('/foo/bar', {parameters:'thisvar=true&thatvar=Howdy',
onSuccess:handlerFunc, onFailure:errFunc});


[powyższy przykład za http://wiki.script.aculo.us/scriptaculous/show/Ajax.Request]

Czasem jednak chcielibyśmy by do funkcji handlerFunc() przekazany został jeszcze jakiś nasz parametr i żeby to przekazanie wyglądało np. tak:

new Ajax.Request('/foo/bar', {parameters:'thisvar=true&thatvar=Howdy',
onSuccess:handlerFunc(index), onFailure:errFunc});


Okazuje się, że można to zrobić banalnie prosto ;-)
Przekazanie handlerFunc(index) jako callbacka spowoduje, że zostanie podjęta próba wywołania takiej funkcji:

handlerFunc(index)(data);

Wystarczy więc by funkcja handlerFunc(index) zwróciła odpowiednią funkcję przyjmującą argument data :-)

function handlerFunc(index) {
return function(data) {
var innerIndex=index;
alert(innerIndex+" "+data.responseText);
}
}

Co ciekawe, gdy użyjemy takiego kodu:

new Ajax.Request('/foo/bar', {parameters:'thisvar=true&thatvar=Howdy',
onSuccess:handlerFunc(1), onFailure:errFunc});
new Ajax.Request('/foo/bar2', {parameters:'thisvar=true&thatvar=Howdy',
onSuccess:handlerFunc(2), onFailure:errFunc});

To funkcja dla pierwszego requesta otrzyma parametr 1, a dla drugiego 2 :-)

Czyż JavaScript nie jest fajny? :-)


Podobne postybeta
Ajax - Prototype
Data binding w Polymerze jest oszukany ;-)
Moja własna akcja w Google Home ;-)
Polymeryzacja AngularJS ;-)
Google Actions działają już w Google Assitant nie tylko na Google Home, ale i w innych jego inkarnacjach :-)