在JavaScript中创建自定义回调

时间:2010-02-03 09:22:42

标签: javascript

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

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

此功能的消费者应该是这样的:

object.LoadData(success);

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

我该如何实现?

10 个答案:

答案 0 :(得分:547)

实际上,你的代码几乎可以正常工作,只需将你的回调声明为参数,你可以使用参数名称直接调用它。

基础知识

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

这将调用doSomething,它将调用foo,这将提醒“东西在这里”。

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

更高级的东西

有时您想要调用回调,以便它看到this的特定值。您可以使用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`

你也可以传递参数:

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`

有时,将要回调的参数作为数组传递是有用的,而不是单独传递。您可以使用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`

答案 1 :(得分:72)

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

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

  callback();
}

答案 2 :(得分:55)

我的2美分。相同但不同......

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


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

答案 3 :(得分:9)

function loadData(callback) {

    //execute other requirement

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

loadData(function(){

   //execute callback

});

答案 4 :(得分:4)

   function callback(e){
      return e;
   }
    var MyClass = {
       method: function(args, callback){
          console.log(args);
          if(typeof callback == "function")
          callback();
       }    
    }

============================================== < / p>

MyClass.method("hello",function(){
    console.log("world !");
});

============================================== < / p>

结果是:

hello world !

答案 5 :(得分:2)

如果要在完成某项操作时执行某项功能。一个很好的解决方案是听取事件。 例如,我将使用ES6实现DispatcherDispatcherEvent类,然后:

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

<强>分派器:

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

快乐的编码!

p / s:缺少我的代码处理一些错误异常

答案 6 :(得分:1)

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

答案 7 :(得分:1)

调用回调函数时,我们可以像下面这样使用它:

consumingFunction(callbackFunctionName)

示例:

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

这是Codepend的完整示例。

答案 8 :(得分:0)

尝试:

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

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

答案 9 :(得分:0)

有些答案虽然正确但可能有点难以理解。以下是外行人的一个例子:

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

回调意味着,&#34;杰克&#34;在显示具有console.log的用户列表之前,始终会将其添加到用户。

Source (YouTube)