最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - NodeJS default parameter when last parameter is the callback - Stack Overflow

programmeradmin3浏览0评论

I have a function like this one (simplified) :

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

I'd like to have a default value for age if it's not provided.

I know I could do doSmthg(name, callback, age=42) {...} in ES6 but I've been told callback should always be the last parameter as it make the call to the function more readable.

For now the solution I found is to do the following :

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

But I find this solution hard to read.

Is this the good solution ? Is there a better one ?

I have a function like this one (simplified) :

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

I'd like to have a default value for age if it's not provided.

I know I could do doSmthg(name, callback, age=42) {...} in ES6 but I've been told callback should always be the last parameter as it make the call to the function more readable.

For now the solution I found is to do the following :

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

But I find this solution hard to read.

Is this the good solution ? Is there a better one ?

Share Improve this question asked Nov 19, 2015 at 13:12 IggYIggY 3,1254 gold badges30 silver badges55 bronze badges 5
  • 1 Is using promises an option? – robertklep Commented Nov 19, 2015 at 13:23
  • @robertklep I never used promises in this project. If it leads to a very "cool" solution I could concider using promises but I'd rather not – IggY Commented Nov 19, 2015 at 13:29
  • Your function declaration would look like this: doSmthg(name, age = 42) (since you don't need to pass a callback anymore). – robertklep Commented Nov 19, 2015 at 13:30
  • @robertklep I'll take a look at this. Thank you :) – IggY Commented Nov 19, 2015 at 13:36
  • I would definitely suggest using promises.. they are first-class language constructs in ES6 and compose significantly better than callbacks. In nearly every library that has callbacks for me ends up having an "invisible" dependency on bluebird because I have to promisify everything. – Dan Commented Nov 19, 2015 at 16:19
Add a comment  | 

3 Answers 3

Reset to default 10

For this kind of situation you can use something like this:

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

Or you can use a Hash of options, that i think it's better because makes the code more readable, depending of the number of parameters:

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

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

Also you can use the underscore #extend function to merge the options with the default values.

If you have access to spread operator:

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

But I think it's time to use promises in NodeJS as well.

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 }

Using ES6 promises you can get rid of the so called "callback pyramid", and makes it possible to use your function with ES7 async-await keywords. The future is here!

Code

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}

Explanation

Depending on the number of arguments to pass it might look too verbose to your liking. The concept should be self explanatory but to put it in words, we group the arguments in an object and inside the function have an object with the default values (if needed). Then we override the defaults with those passed leaving us a very clear and clean callback and verbose args.

Note that if extra parameters are passed, those are not lost in the process of setting the defaults.

发布评论

评论列表(0)

  1. 暂无评论