NodeJS默认参数,当最后一个参数是回调时

NodeJS default parameter when last parameter is the callback

本文关键字:参数 回调 最后一个 默认 NodeJS      更新时间:2023-09-26

我有一个类似的函数(简化):

doSmthg (name, age, callback) {
  callback(name, age);
}

如果没有提供,我希望有一个默认的年龄值。

我知道我可以在ES6中执行doSmthg(name, callback, age=42) {...},但我被告知回调应该始终是最后一个参数,因为它可以使对函数的调用更可读。

目前,我发现的解决方案是做以下事情:

doSmthg (name, age, callback) {
  if (arguments.length === 2) {
    age = 42;
    callback = age;
  }
}

但我发现这个解决方案很难阅读。

这是一个好的解决方案吗?有更好的吗?

对于这种情况,您可以使用以下内容:

function doSmthg(name, age, callback) {
  if (typeof age === 'function') {
    callback = age;
    age = DEFAULT_VALUE;
  }
  //continue
}

或者你可以使用选项的哈希,我认为这更好,因为根据参数的数量,代码更可读:

function doSmthg(options, callback) {
  var name = options.name;
  var age = options.age || DEFAULT_VALUE;
  //continue
}
doSmthg({ name: 'batman' }, function() {});

还可以使用下划线#extend函数将选项与默认值合并。

如果您可以访问排列运算符:

function foo(...args) {
  const callback = args.pop();
  const [name, age = 42] = args;
  // ...  
}

但我认为现在也是时候在NodeJS中使用promise了。

function foo(name, age = 42) {
  return new Promise(resolve => {
    setTimeout(() => resolve({name, age}), 1000);
  });
}
//...
foo('Sándor').then(x => console.log(x)); // { name:"Sándor", age:42 }

使用ES6 promise,您可以摆脱所谓的"回调金字塔",并使使用ES7 async-await关键字的函数成为可能。未来就在这里!

代码

function foo(args, callback){
    parsed = {name:"John Doe",age:12};      //default values
    for(a in args) parsed[a] = args[a];
    //Arguments are accessible like parsed.name
    callback(parsed);
}
function callback(args){
    alert(JSON.stringify(args));
}

foo({name:"Peter",extra:2},callback);//yields {"name":"Peter","age":12,"extra":2}
foo({name:"Mark",age:92},callback);  //yields {"name":"Mark","age":92}
foo({},callback);                    //yields {"name":"John Doe","age":12}

解释

根据要传递的参数的数量,它可能看起来过于冗长。这个概念应该是不言自明的,但换句话说,我们将参数分组在一个对象中,函数内部有一个具有默认值的对象(如果需要的话)。然后,我们用传递的参数覆盖默认值,留下一个非常清晰的callback和详细的参数。

请注意,如果传递了额外的参数,这些参数在设置默认值的过程中不会丢失。