【问题标题】:Javascript Callbacks with custom aguments带有自定义参数的 Javascript 回调
【发布时间】:2012-05-10 23:32:47
【问题描述】:

鉴于我不知道参数可能是什么,我正在尝试研究如何在节点中实现异步回调。

我将说明我正在尝试执行的同步版本,以便更清楚地说明这一点。

function isAuthorized(userID){
    // check for user Permissions here
    return isAuthorized;
}

使用这个任何函数都可以调用它,并根据它返回的值来确定用户是否被授权。但是,我用来获取用户 ID(并检查权限)的函数都是异步函数并且需要回调。但是,当我不知道回调中所需的参数时,我不知道如何实现它。

调用它的函数可能想要向回调发送一些参数(通常它只是等待同步返回),这让我感到困惑。

function isAuthorized(socket, callback, args){
    socket.get('userID', function (err, userID) {
        //check userID for permission
        callback(args);
    });
}

我意识到我可以将参数转换为数组并发送该数组,但我想知道是否有更通用的方法来执行此操作,它不会强迫我将所有回调从参数数组转换.

希望你能帮忙, 采摘采摘

【问题讨论】:

  • 你熟悉Function.appy()Function.call()吗?您可以简单地这样做:callback.apply(this, args),其中args 是一个数组。

标签: javascript node.js asynchronous


【解决方案1】:

您始终可以创建一个函数来为您将这些参数拉入一个数组,然后在您的每个异步函数中重用它:

function asyncWithCallbackArgs(obj, callback) {
  var args = Array.prototype.slice.call(arguments, 2);
  callback.apply(obj, args);
}

这将使您能够执行以下操作:

function callback (c, d, e, f) {
  console.log([c, d, e, f]);
}

asyncWithCallbackArgs({}, callback,'c','d','e','f');​

有一个小提琴 here 可以玩。

【讨论】:

  • 虽然我很欣赏仅发送一个对象并将其作为回调返回的想法,但这回答了我的问题并完全符合我的想法。
【解决方案2】:

我不确定,如果我以正确的方式理解您,但您似乎正在函数 (MDN link) 中寻找 arguments 对象。

基本上这样您就不必提前指定任何参数,而是让函数查找存在的参数。因此,您可以执行以下操作:

function myFunc() {
  for (var i=0; i<arguments.length; ++i ) {
    console.log( arguments[i] );
  }
}

这会产生类似的输出

myFunc( 1 );
> 1
myFunc( 's', 3, 'S' );
> "s"
> 3
> "S"

【讨论】:

    【解决方案3】:

    因此,当您构建 API 时,您需要指定将参数传递到回调的顺序。因此,您需要很好地注释您的代码,以便使用您的 API 的任何人都可以了解他们将从您的方法中得到什么。

    听起来您可能想要传回不同的参数,具体取决于传入的回调函数的样子。这不是传统上 API 的工作方式。要有效地做到这一点需要相当长的时间。

    我建议将对象传递给回调。 Object 可以有多个参数,人们可以从中提取出来。这将简化未来的增强,因为您可以非常简单地向该对象添加一个附加属性,而不会弄乱每个人对您的方法的实现。所以,返回这样的东西:

    {
        "id": "Some_ID",
        "message": "Some Message",
        "isAuthorized" : true
    }
    

    这样,任何使用您的 API 的人都不必在回调方法中考虑多个参数。他们知道他们只会得到一个 arg,并且它将是一个具有多个属性的 Obj,他们可以使用他们想要的属性。此外,将来您可以在不破坏代码的情况下添加第 4 或第 5 个属性。您可以添加一个“日期时间”属性,它们的代码将保持不变。您将获得向后兼容性,然后新的实现者可以使用新属性。

    【讨论】:

      【解决方案4】:

      如果我的理解正确,请不要将它们作为参数传递:

      var a = "something";
      var b = "something";
      
      var callback = function(){
         // use a and b here
      };
      
      isAuthorized(socket, callback);
      

      http://jsfiddle.net/S4tH6/

      【讨论】:

      • 我不认为他在问如何给自己一个回调。他想知道如何调用已提供给他的回调。不过我可能是错的。这个问题不是很清楚。
      • 是的,很抱歉。我应该添加更多上下文。我有一些带有设置参数的回调函数(我无法修改它)。我宁愿通过身份验证快速发送它,然后发送到更合适的函数来处理信息。但我现在有了答案。
      【解决方案5】:

      在 Coffee-script 中有一个叫做 splats 的东西。

      ( socket, callback, args... )->
      
        callback args...
      

      这在 Javascript 中翻译为以下内容:

      var __slice = [].slice;
      
      function() {
        var args, callback, socket;
        socket = arguments[0], callback = arguments[1], args = 3 <= arguments.length ?__slice.call(arguments, 2) : [];
        return callback.apply(null, args);
      };
      

      【讨论】:

        猜你喜欢
        • 2019-11-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-26
        • 2011-07-05
        • 2012-09-24
        • 2012-12-13
        • 1970-01-01
        相关资源
        最近更新 更多