在JavaScript中创建一个自定义回调

时间:2022-08-10 01:20:14

All I need to do is to execute a callback function when my current function execution ends.

我需要做的就是在当前函数执行结束时执行回调函数。

function LoadData() 
{
    alert('The data has been loaded');
    //Call my callback with parameters. For example,
    //callback(loadedData , currentObject);
}

A consumer for this function should be like this:

这个函数的使用者应该是这样的:

object.LoadData(success);

function success(loadedData , currentObject) 
{
  //Todo: some action here 
}

How do I implement this?

我如何实现它?

10 个解决方案

#1


511  

Actually, your code will pretty much work as is, just declare your callback as an argument and you can call it directly using the argument name.

实际上,您的代码基本上可以正常工作,只要将回调声明为参数,就可以使用参数名直接调用它。

The basics

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

That will call doSomething, which will call foo, which will alert "stuff goes here".

它会调用doSomething,它会调用foo,它会发出“东西到这里”的警报。

Note that it's very important to pass the function reference (foo), rather than calling the function and passing its result (foo()). In your question, you do it properly, but it's just worth pointing out because it's a common error.

注意,传递函数引用(foo)非常重要,而不是调用函数并传递其结果(foo())。在你的问题中,你做得很好,但值得指出的是,这是一个常见的错误。

More advanced stuff

Sometimes you want to call the callback so it sees a specific value for this. You can easily do that with the JavaScript call function:

有时候你想调用回调函数,这样它就会看到这个函数的特定值。通过JavaScript调用函数,您可以很容易地做到这一点:

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`

You can also pass arguments:

你也可以通过参数:

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`

Sometimes it's useful to pass the arguments you want to give the callback as an array, rather than individually. You can use apply to do that:

有时,将希望作为数组而不是单独给出回调的参数传递出去是很有用的。你可以用apply来做:

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`

#2


67  

It is good practice to make sure the callback is an actual function before attempting to execute it:

在尝试执行回调之前,确保回调是一个实际的函数,这是一个很好的实践:

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

  callback();
}

#3


50  

My 2 cent. Same but different...

我的2美分,相同但不同……

<script>
    dosomething("blaha", function(){
        alert("Yay just like jQuery callbacks!");
    });


    function dosomething(damsg, callback){
        alert(damsg);
        if(typeof callback == "function") 
        callback();
    }
</script>

#4


8  

function loadData(callback) {

    //execute other requirement

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

loadData(function(){

   //execute callback

});

#5


3  

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

==============================================

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

Result is:

结果是:

hello world !

#6


1  

function LoadData(callback) 
{
    alert('the data have been loaded');
    callback(loadedData, currentObject);
}

#7


1  

When calling the callback function, we could use it like below:

调用回调函数时,可以如下所示:

consumingFunction(callbackFunctionName)

consumingFunction(callbackFunctionName)

Example:

例子:

// 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

This is the Codepend with full example.

这是与完整示例的Codepend。

#8


0  

Try:

试一试:

function LoadData (callback)
{
    // ... Process whatever data
    callback (loadedData, currentObject);
}

Functions are first class in JavaScript; you can just pass them around.

函数是JavaScript中的第一类;你可以把它们传过来。

#9


0  

Some of the answers, while correct may be a little tricky to understand. Here is an example in layman's terms:

有些答案虽然正确,但理解起来可能有点棘手。这是一个外行的例子:

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

The callback means, "Jake" is always added to the users before displaying the list of users with console.log.

回调意味着,在使用console.log显示用户列表之前,总是向用户添加“Jake”。

Source (YouTube)

源(YouTube)

#10


0  

If you want to execute a function when something is done. One of a good solution is to listen to events. For example, I'll implement a Dispatcher, a DispatcherEvent class with ES6,then:

如果你想在某件事完成时执行一个函数。一个好的解决方案是倾听事件。例如,我将使用ES6实现一个Dispatcher、DispatcherEvent类,然后:

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:

DispatcherEvent:

class DispatcherEvent{
  constructor(eventName){
    this.eventName = eventName
    this.callbacks = []
  }

  registerCallback(callback){
    this.callbacks.push(callback)
  }

  fire(data){
    this.callbacks.forEach((callback=>{
      callback(data)
    }))
  }
}

Happy coding!

编码快乐!

p/s: My code is missing handle some error exceptions

我的代码丢失了处理一些错误异常

#1


511  

Actually, your code will pretty much work as is, just declare your callback as an argument and you can call it directly using the argument name.

实际上,您的代码基本上可以正常工作,只要将回调声明为参数,就可以使用参数名直接调用它。

The basics

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

That will call doSomething, which will call foo, which will alert "stuff goes here".

它会调用doSomething,它会调用foo,它会发出“东西到这里”的警报。

Note that it's very important to pass the function reference (foo), rather than calling the function and passing its result (foo()). In your question, you do it properly, but it's just worth pointing out because it's a common error.

注意,传递函数引用(foo)非常重要,而不是调用函数并传递其结果(foo())。在你的问题中,你做得很好,但值得指出的是,这是一个常见的错误。

More advanced stuff

Sometimes you want to call the callback so it sees a specific value for this. You can easily do that with the JavaScript call function:

有时候你想调用回调函数,这样它就会看到这个函数的特定值。通过JavaScript调用函数,您可以很容易地做到这一点:

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`

You can also pass arguments:

你也可以通过参数:

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`

Sometimes it's useful to pass the arguments you want to give the callback as an array, rather than individually. You can use apply to do that:

有时,将希望作为数组而不是单独给出回调的参数传递出去是很有用的。你可以用apply来做:

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`

#2


67  

It is good practice to make sure the callback is an actual function before attempting to execute it:

在尝试执行回调之前,确保回调是一个实际的函数,这是一个很好的实践:

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

  callback();
}

#3


50  

My 2 cent. Same but different...

我的2美分,相同但不同……

<script>
    dosomething("blaha", function(){
        alert("Yay just like jQuery callbacks!");
    });


    function dosomething(damsg, callback){
        alert(damsg);
        if(typeof callback == "function") 
        callback();
    }
</script>

#4


8  

function loadData(callback) {

    //execute other requirement

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

loadData(function(){

   //execute callback

});

#5


3  

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

==============================================

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

Result is:

结果是:

hello world !

#6


1  

function LoadData(callback) 
{
    alert('the data have been loaded');
    callback(loadedData, currentObject);
}

#7


1  

When calling the callback function, we could use it like below:

调用回调函数时,可以如下所示:

consumingFunction(callbackFunctionName)

consumingFunction(callbackFunctionName)

Example:

例子:

// 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

This is the Codepend with full example.

这是与完整示例的Codepend。

#8


0  

Try:

试一试:

function LoadData (callback)
{
    // ... Process whatever data
    callback (loadedData, currentObject);
}

Functions are first class in JavaScript; you can just pass them around.

函数是JavaScript中的第一类;你可以把它们传过来。

#9


0  

Some of the answers, while correct may be a little tricky to understand. Here is an example in layman's terms:

有些答案虽然正确,但理解起来可能有点棘手。这是一个外行的例子:

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

The callback means, "Jake" is always added to the users before displaying the list of users with console.log.

回调意味着,在使用console.log显示用户列表之前,总是向用户添加“Jake”。

Source (YouTube)

源(YouTube)

#10


0  

If you want to execute a function when something is done. One of a good solution is to listen to events. For example, I'll implement a Dispatcher, a DispatcherEvent class with ES6,then:

如果你想在某件事完成时执行一个函数。一个好的解决方案是倾听事件。例如,我将使用ES6实现一个Dispatcher、DispatcherEvent类,然后:

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:

DispatcherEvent:

class DispatcherEvent{
  constructor(eventName){
    this.eventName = eventName
    this.callbacks = []
  }

  registerCallback(callback){
    this.callbacks.push(callback)
  }

  fire(data){
    this.callbacks.forEach((callback=>{
      callback(data)
    }))
  }
}

Happy coding!

编码快乐!

p/s: My code is missing handle some error exceptions

我的代码丢失了处理一些错误异常

相关文章