Lepsze zrozumienie funkcji zwrotnych w JavaScript

Rozumiem przekazywanie funkcji do innej funkcji jako wywołanie zwrotne i zlecanie jej wykonania, ale nie rozumiem najlepszej implementacji, aby to zrobić. Szukam bardzo podstawowego przykładu, jak ten:

var myCallBackExample = {
    myFirstFunction : function( param1, param2, callback ) {
        // Do something with param1 and param2.
        if ( arguments.length == 3 ) {
            // Execute callback function.
            // What is the "best" way to do this?
        }
    },
    mySecondFunction : function() {
        myFirstFunction( false, true, function() {
            // When this anonymous function is called, execute it.
        });
    }
};

W myFirstFunction, jeśli zwracam nową metodę callback(), to działa i wykonuje funkcję anonimową, ale nie wydaje się to dla mnie właściwym podejściem.

Author: franzlorenzon, 2009-01-27

8 answers

Możesz po prostu powiedzieć

callback();

Alternatywnie możesz użyć metody call, jeśli chcesz dostosować wartość this w wywołaniu zwrotnym.

callback.call( newValueForThis);

Wewnątrz funkcji this byłoby czymkolwiek newValueForThis jest.

 131
Author: krosenvold,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-12 14:08:03

Należy sprawdzić, czy wywołanie zwrotne istnieje i jest funkcją wykonywalną:

if (callback && typeof(callback) === "function") {
    // execute the callback, passing parameters as necessary
    callback();
}

Wiele bibliotek (jQuery, dojo itp.) używają podobnego wzorca dla swoich funkcji asynchronicznych, a także węzłów.js dla wszystkich funkcji asynchronicznych (NodeJS Zwykle przekazuje error i data do wywołania zwrotnego). Patrząc na ich kod źródłowy pomoże!

 89
Author: arunjitsingh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-22 17:11:50

Istnieją 3 główne możliwości wykonania funkcji:

var callback = function(x, y) {
    // "this" may be different depending how you call the function
    alert(this);
};
  1. callback(argument_1, argument_2);
  2. / Align = "left" / call (some_object, argument_1, argument_2); / Align = "left" / apply (some_object, [argument_1, argument_2]);

Wybrana metoda zależy od tego, czy:

  1. argumenty są przechowywane w tablicy lub jako odrębne zmienne.
  2. chcesz wywołać tę funkcję w kontekście jakiegoś obiektu. W tym przypadku, używając słowa kluczowego "this" w tym wywołaniu zwrotnym odwołuje się do obiektu przekazanego jako argument w call () lub apply (). Jeśli nie chcesz przekazać kontekstu obiektu, użyj null lub undefined. W tym drugim przypadku obiekt globalny zostałby użyty do "tego".

Docs for Function.call , funkcja.zastosuj

 34
Author: Ionuț G. Stan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-27 11:52:30

Wywołania zwrotne dotyczą sygnałów, a "nowe" - tworzenia instancji obiektów.

W tym przypadku byłoby jeszcze bardziej odpowiednie, aby wykonać tylko "callback ();" niż " return new callback ()", ponieważ i tak nie robisz nic z wartością zwracaną.

(i argumenty.length = = 3 test jest naprawdę niezgrabny, fwiw, lepiej sprawdzić, czy param callback istnieje i jest funkcją.)

 6
Author: annakata,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-27 11:43:31

Właściwą implementacją byłoby:

if( callback ) callback();

To sprawia, że parametr callback jest opcjonalny..

 6
Author: faeb187,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-03 12:21:07

Możesz użyć:

if (callback && typeof(callback) === "function") {
    callback();
}

Poniższy przykład jest nieco bardziej wyczerpujący:

function mySandwich(param1, param2, callback) {
alert('Started eating my sandwich.\n\nIt has: ' + param1 + ', ' + param2);
var sandwich = {toppings: [param1, param2]},
    madeCorrectly = (typeof(param1) === "string" && typeof(param2) === "string") ? true : false;
if (callback && typeof(callback) === "function") {  
    callback.apply(sandwich, [madeCorrectly]);  
  }  
}  

mySandwich('ham', 'cheese', function(correct) {
if(correct) {
    alert("Finished eating my " + this.toppings[0] + " and " + this.toppings[1] + " sandwich.");
} else {
    alert("Gross!  Why would I eat a " + this.toppings[0] + " and " + this.toppings[1] + " sandwich?");
  }
});
 2
Author: Hasan A Yousef,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-21 19:03:24
function checkCallback(cb)
{
    if(cb || cb!='')
    {
        if(typeof window[cb] === 'undefined') alert('Callback function not found.');
        else window[cb].call(this,Arg1, Arg2);
    }
}
 1
Author: Aamir Afridi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-06 16:06:53

Możesz spojrzeć w tym linku dodam dla Ciebie podstawowy przykład, który wyjaśnia funkcję call back w javascript. jsfiddle

var x=0;

function testCallBack(param1, param2, callback) {
    alert('param1= ' + param1 + ', param2= ' + param2+' X='+x);
    if (callback && typeof(callback) === "function") {
        x+=1;
        alert("Calla Back x= "+x);
        x+=1;
        callback();
    }
}


testCallBack('ham', 'cheese',function(){
alert("Function X= "+x);
});
 1
Author: BERGUIGA Mohamed Amine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-24 15:08:56