Tworzenie niestandardowego połączenia zwrotnego w JavaScript
Wszystko, co muszę zrobić, to wykonać funkcję zwrotną, gdy kończy się moja bieżąca realizacja funkcji.
function LoadData()
{
alert('The data has been loaded');
//Call my callback with parameters. For example,
//callback(loadedData , currentObject);
}
Konsument dla tej funkcji powinien wyglądać następująco:
object.LoadData(success);
function success(loadedData , currentObject)
{
//Todo: some action here
}
Jak to zaimplementować?
10 answers
Właściwie, Twój kod będzie działać tak, jak jest, po prostu zadeklaruj swoje wywołanie zwrotne jako argument i możesz wywołać go bezpośrednio za pomocą nazwy argumentu.
Podstawy
function doSomething(callback) {
// ...
// Call the callback
callback('stuff', 'goes', 'here');
}
function foo(a, b, c) {
// I'm the callback
alert(a + " " + b + " " + c);
}
doSomething(foo);
Które wywołają doSomething
, które wywołują foo
, które ostrzegają "rzeczy idą tutaj".
Zauważ, że bardzo ważne jest, aby przekazać odwołanie do funkcji (foo
), zamiast wywoływać funkcję i przekazywać jej wynik (foo()
). W twoim pytaniu robisz to poprawnie, ale warto wskazując, ponieważ jest to częsty błąd.
Bardziej zaawansowane rzeczy
Czasami chcesz wywołać callback, aby zobaczył określoną wartość dla this
. Możesz to łatwo zrobić za pomocą funkcji JavaScript call
:
function Thing(name) {
this.name = name;
}
Thing.prototype.doSomething = function(callback) {
// Call our callback, but using our own instance as the context
callback.call(this);
}
function foo() {
alert(this.name);
}
var t = new Thing('Joe');
t.doSomething(foo); // Alerts "Joe" via `foo`
Można również podać argumenty:
function Thing(name) {
this.name = name;
}
Thing.prototype.doSomething = function(callback, salutation) {
// Call our callback, but using our own instance as the context
callback.call(this, salutation);
}
function foo(salutation) {
alert(salutation + " " + this.name);
}
var t = new Thing('Joe');
t.doSomething(foo, 'Hi'); // Alerts "Hi Joe" via `foo`
Czasami warto przekazać argumenty, które chcemy przekazać jako tablicę, a nie pojedynczo. Możesz użyć apply
, aby to zrobić:
function Thing(name) {
this.name = name;
}
Thing.prototype.doSomething = function(callback) {
// Call our callback, but using our own instance as the context
callback.apply(this, ['Hi', 3, 2, 1]);
}
function foo(salutation, three, two, one) {
alert(salutation + " " + this.name + " - " + three + " " + two + " " + one);
}
var t = new Thing('Joe');
t.doSomething(foo); // Alerts "Hi Joe - 3 2 1" via `foo`
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
2016-05-16 05:27:49
Dobrą praktyką jest upewnienie się, że wywołanie zwrotne jest rzeczywistą funkcją przed próbą jej wykonania:
if (callback && typeof(callback) === "function") {
callback();
}
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-03-10 23:21:52
Mój 2 cent. To samo, ale inne...
<script>
dosomething("blaha", function(){
alert("Yay just like jQuery callbacks!");
});
function dosomething(damsg, callback){
alert(damsg);
if(typeof callback == "function")
callback();
}
</script>
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-12-09 15:23:31
function loadData(callback) {
//execute other requirement
if(callback && typeof callback == "function"){
callback();
}
}
loadData(function(){
//execute callback
});
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-09-07 09:44:44
function callback(e){
return e;
}
var MyClass = {
method: function(args, callback){
console.log(args);
if(typeof callback == "function")
callback();
}
}
==============================================
MyClass.method("hello",function(){
console.log("world !");
});
==============================================
Wynik to:
hello world !
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
2014-08-05 21:05:04
Jeśli chcesz wykonać funkcję, gdy coś jest zrobione. Jednym z dobrych rozwiązań jest słuchanie wydarzeń.
Na przykład zaimplementuję Dispatcher
, A DispatcherEvent
klasę z ES6, następnie:
let Notification = new Dispatcher()
Notification.on('Load data success', loadSuccessCallback)
const loadSuccessCallback = (data) =>{
...
}
//trigger a event whenever you got data by
Notification.dispatch('Load data success')
Dispatcher:
class Dispatcher{
constructor(){
this.events = {}
}
dispatch(eventName, data){
const event = this.events[eventName]
if(event){
event.fire(data)
}
}
//start listen event
on(eventName, callback){
let event = this.events[eventName]
if(!event){
event = new DispatcherEvent(eventName)
this.events[eventName] = event
}
event.registerCallback(callback)
}
//stop listen event
off(eventName, callback){
const event = this.events[eventName]
if(event){
delete this.events[eventName]
}
}
}
DispatcherEvent:
class DispatcherEvent{
constructor(eventName){
this.eventName = eventName
this.callbacks = []
}
registerCallback(callback){
this.callbacks.push(callback)
}
fire(data){
this.callbacks.forEach((callback=>{
callback(data)
}))
}
}
Szczęśliwego kodowania!
P/ s: brakuje mojego kodu obsługuj niektóre wyjątki błędów
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
2018-04-16 07:21:22
Niektóre odpowiedzi, choć poprawne, mogą być nieco trudne do zrozumienia. Oto przykład w pojęciach laika:
var users = ["Sam", "Ellie", "Bernie"];
function addUser(username, callback)
{
setTimeout(function()
{
users.push(username);
callback();
}, 200);
}
function getUsers()
{
setTimeout(function()
{
console.log(users);
}, 100);
}
addUser("Jake", getUsers);
Wywołanie zwrotne oznacza, że "Jake" jest zawsze dodawany do użytkowników przed wyświetlaniem listy użytkowników z console.log
.
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
2018-02-06 00:04:44
function LoadData(callback)
{
alert('the data have been loaded');
callback(loadedData, currentObject);
}
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
2014-07-21 14:28:49
Podczas wywoływania funkcji callback, możemy użyć jej jak poniżej:
consumingFunction(callbackFunctionName)
Przykład:
// Callback function only know the action,
// but don't know what's the data.
function callbackFunction(unknown) {
console.log(unknown);
}
// This is a consuming function.
function getInfo(thenCallback) {
// When we define the function we only know the data but not
// the action. The action will be deferred until excecuting.
var info = 'I know now';
if (typeof thenCallback === 'function') {
thenCallback(info);
}
}
// Start.
getInfo(callbackFunction); // I know now
To jest Codepend z pełnym przykładem.
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
2017-04-07 13:57:38
Try:
function LoadData (callback)
{
// ... Process whatever data
callback (loadedData, currentObject);
}
Funkcje są pierwszą klasą w JavaScript ; możesz je po prostu przekazać.
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-02-19 09:28:13