更好地理解 JavaScript 中的回调函数

Posted

技术标签:

【中文标题】更好地理解 JavaScript 中的回调函数【英文标题】:Getting a better understanding of callback functions in JavaScript 【发布时间】:2010-10-03 17:48:00 【问题描述】:

我了解将一个函数作为回调传递给另一个函数并让它执行,但我不了解执行此操作的最佳实现。我正在寻找一个非常基本的示例,如下所示:

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

在 myFirstFunction 中,如果我返回 new callback(),那么它会工作并执行匿名函数,但这对我来说似乎不是正确的方法。

【问题讨论】:

在什么意义上正确?通常回调用于事件处理程序——最显着的是 Ajax 调用,它是异步的——基本上是你不知道何时(或是否)响应会到来的事情。 顺便说一句,参数是数组,但不是数组,所以你不能做 argument.length 但你可以使用 slice 方法将它转换成数组... @paul,虽然arguments 不是数组是对的,但您仍然可以将其长度引用为arguments.length——试一试。该属性指的是实际传入的参数个数,不一定是函数签名中的参数个数。 【参考方案1】:

你可以使用:

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

下面的例子更全面:

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】:

function checkCallback(cb) 
  if (cb || cb != '') 
    if (typeof window[cb] === 'undefined') alert('Callback function not found.');
    else window[cb].call(this, Arg1, Arg2);
  

【讨论】:

【参考方案3】:

这是一个解释 javascriptcallback() 函数的基本示例:

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

JSFiddle

【讨论】:

【参考方案4】:

你可以说

callback();

如果您想在回调中调整this 的值,也可以使用call 方法。

callback.call( newValueForThis);

在函数this 内部将是newValueForThis 的任何内容。

【讨论】:

【参考方案5】:

你应该检查回调是否存在,并且是一个可执行函数:

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

许多库(jQuery、dojo 等)的异步函数使用类似的模式,所有异步函数也使用 node.js(nodejs 通常将errordata 传递给回调)。查看他们的源代码会有所帮助!

【讨论】:

你为什么要把callback转换成字符串然后检查它的类型?这会提高性能吗?这就像检查类型,检查转换后的布尔值是否返回 true,然后再次检查其类型并针对字符串进行测试......你能解释一下原因吗? 我很好奇为什么你需要回调的第一个断言......是检查 null 还是 undefined? typeof(callback) 不会为您实现吗? typeof(null) === "Object", typeof("undefined") === "undefined" 短路与。如果回调不存在,不要费心计算它的类型。虽然,你是对的。 typeof() 不需要它,但我会做一个 jsperf 看看短路是否值得。 @headacheCoder - callback 没有被强制转换为字符串,在调用它之前正在检查它的类型以查看它是否是一个函数。该代码可能接受callback 作为参数,并且不确定该参数是否为可调用类型——或者参数可能是各种类型,以试图提供一种多态形式,其中代码可能对不同的typeof 做出不同的反应论据。【参考方案6】:

正确的实现是:

if( callback ) callback();

这使得回调参数可选..

【讨论】:

如果回调参数不是函数怎么办?【参考方案7】:

执行函数有 3 种主要可能性:

var callback = function(x, y) 
    // "this" may be different depending how you call the function
    alert(this);
;
    回调(argument_1,argument_2); callback.call(some_object, argument_1, argument_2); callback.apply(some_object, [argument_1, argument_2]);

您选择的方法取决于:

    您将参数存储在数组中或作为不同的变量。 您想在某个对象的上下文中调用该函数。在这种情况下,在回调中使用“this”关键字将引用在 call() 或 apply() 中作为参数传递的对象。如果您不想传递对象上下文,请使用 null 或 undefined。在后一种情况下,全局对象将用于“this”。

Function.call 的文档, Function.apply

【讨论】:

【参考方案8】:

回调是关于信号的,而“new”是关于创建对象实例的。

在这种情况下,只执行“callback();”会更合适。而不是“return new callback()”,因为无论如何你都没有对返回值做任何事情。

(而且 arguments.length==3 测试真的很笨重,fwiw,最好检查回调参数是否存在并且是一个函数。)

【讨论】:

以上是关于更好地理解 JavaScript 中的回调函数的主要内容,如果未能解决你的问题,请参考以下文章

理解javascript中的回调函数(callback)

了解嵌套回调和范围?

JavaScript中的回调函数

理解javascript中的回调函数(callback)

理解回调函数

javascript回调函数的理解