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

时间:2015-11-19 13:12:47

标签: javascript node.js ecmascript-6

我有一个像这样的功能(简化):

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

但我觉得这个解决方案难以阅读。

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

3 个答案:

答案 0 :(得分:9)

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

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

或者您可以使用Hash of options,我认为它更好,因为根据参数的数量使代码更具可读性:

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

doSmthg({ name: 'batman' }, function() {});

此外,您可以使用underscore #extend function将选项与默认值合并。

答案 1 :(得分:7)

如果您有权使用传播运营商:

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

但我认为是时候在NodeJS中使用promises了。

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承诺,您可以摆脱所谓的“回调金字塔”,并且可以将您的功能与ES7 async-await关键字一起使用。未来就在这里!

答案 2 :(得分:3)

代码

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和详细的args。

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