1

intercom-clientgithub 中,我看到了这段代码:

client.users.list(function (d) {
  // d is the response from the server
});

// Or

client.users.list(function (err, d) {
  // err is an error response object, or null
  // d is a successful response object, or null
});

我的问题是:如何intercom知道我是否通过funcrtion(err,d)或只是function(data).

我检查了源代码,发现他们使用bluebird库。蓝鸟是如何做到的?

我希望我的功能也能做到这一点。

换句话说:

function myFunction(data,callback){
  if (callbackListenToErrArgument(callback)) 
       callback(null,data)
   else
       callback(data)

}

如何实现callbackListenToErrArgument功能?

4

2 回答 2

3

可以检查.length传递函数的属性。该.length属性是为函数定义的参数数量。

function hasErrorArgument(callback) {
  if (callback.length < 2) { return false; } // Has 1 or 0.
  else return true; // has 2 or more
} // Yes, I know it can be reduced to one line. Sue me.

请注意:这是不好的做法。您应该为您接受的回调提供统一的签名。(err, data) => {}是一个很好的签名。

或者更好的是,让你的list()函数返回一个Promise对象:(仅在某些浏览器中原生支持 Promise。使用前检查兼容性,或使用 polyfill 或库)。

client.users.list()
  .then(listOfUsers => {
    // Use data here
  })
  .catch(err => {
    // Handle errors here
  });
于 2016-02-08T13:34:20.197 回答
0

假设查看方法长度:

fun=function(a,b,c) {
  console.log(a,b,c)
}
(a,b,c) {
  console.log(a,b,c)
}
fun.prototype.constructor.length
3

正如@madara-uchiha 所说,可能被认为是一种不好的做法,该bluebird库有一个方法调用函数,即:

var makeMethodCaller = function (methodName) {
    return new Function("ensureMethod", "                                    \n\
        return function(obj) {                                               \n\
            'use strict'                                                     \n\
            var len = this.length;                                           \n\
            ensureMethod(obj, 'methodName');                                 \n\
            switch(len) {                                                    \n\
                case 1: return obj.methodName(this[0]);                      \n\
                case 2: return obj.methodName(this[0], this[1]);             \n\
                case 3: return obj.methodName(this[0], this[1], this[2]);    \n\
                case 0: return obj.methodName();                             \n\
                default:                                                     \n\
                    return obj.methodName.apply(obj, this);                  \n\
            }                                                                \n\
        };                                                                   \n\
        ".replace(/methodName/g, methodName))(ensureMethod);
};

[更新] 我添加了 Bluebird 代码的工作片段来讨论它。正如有人所说,这似乎适用于其他东西,即使在 switch 案例中有一个方法长度保护。检查代码:

var console={}
console.log=function(msgs) { document.writeln(msgs)};

var makeMethodCaller = function (methodName) {
    return new Function("ensureMethod", "                                    \n\
        return function(obj) {                                               \n\
            var len = this.length;                                           \n\
            console.log(\"Who is this\"+this);                                           \n\
            ensureMethod(obj, 'methodName');                                 \n\
            switch(len) {                                                    \n\
                case 1: return obj.methodName(this[0]);                      \n\
                case 2: return obj.methodName(this[0], this[1]);             \n\
                case 3: return obj.methodName(this[0], this[1], this[2]);    \n\
                case 0: return obj.methodName();                             \n\
                default:                                                     \n\
                    return obj.methodName.apply(obj, this);                  \n\
            }                                                                \n\
        };                                                                   \n\
        ".replace(/methodName/g, methodName))(ensureMethod);
};
function ensureMethod(obj, methodName) {
    var fn;
    if (obj != null) fn = obj[methodName];
    if (typeof fn !== "function") {
        var message = "Object " + JSON.stringify(obj) + " has no method '" +
            JSON.stringify(methodName) + "'";
        throw new Error(message);
    }
    return fn;
}
var fn=makeMethodCaller("callMe");


console.log(fn)

var obj0= {
 callMe : function() { console.log("\n\n\ncalled with 0 params")}
};
var obj1= {
 callMe : function(a) { console.log("\n\n\ncalled with 1 params")}
};
var obj2= {
 callMe : function(a,b) { console.log("\n\n\ncalled 2 params")}
};
var obj3= {
 callMe : function(a,b,c) { console.log("\n\n\ncalled 3 params")}
};


[obj0,obj1,obj2,obj3].map(function(e) { 
  return fn( e );
});

于 2016-02-08T13:45:11.613 回答