可选回调的 JavaScript 样式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6792663/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 23:12:19  来源:igfitidea点击:

JavaScript style for optional callbacks

javascriptcoding-stylecallback

提问by henry.oswald

I have some functions which occasionally (not always) will receive a callback and run it. Is checking if the callback is defined/function a good style or is there a better way?

我有一些函数偶尔(并非总是)会收到回调并运行它。检查回调是否定义/函数是一种很好的风格还是有更好的方法?

Example:

例子:

function save (callback){
   .....do stuff......
   if(typeof callback !== 'undefined'){
     callback();
   };
};

回答by Raynos

I personally prefer

我个人更喜欢

typeof callback === 'function' && callback();

typeof callback === 'function' && callback();

The typeofcommand is dodgy however and should only be used for "undefined"and "function"

typeof然而,该命令是狡猾的,应该只用于"undefined""function"

The problems with the typeof !== undefinedis that the user might pass in a value that is defined and not a function

的问题typeof !== undefined在于用户可能传入一个已定义的值而不是一个函数

回答by Pablo Fernandez

You can also do:

你也可以这样做:

var noop = function(){}; // do nothing.

function save (callback){
   callback = callback || noop;
   .....do stuff......
};

It's specially useful if you happen to use the callbackin a few places.

如果你碰巧callback在几个地方使用它,它特别有用。

Additionally if you are using jQuery, you already have a function like that, it's called $.noop

此外,如果您正在使用jQuery,那么您已经有一个这样的函数,它被称为$.noop

回答by ninja123

Simply do

简单地做

if (callback) callback();

I prefer to call the callback if supplied, no matter what type it is. Don't let it fail silently, so the implementor knows he passed in an incorrect argument and can fix it.

如果提供,我更喜欢调用回调,无论它是什么类型。不要让它默默地失败,所以实现者知道他传入了一个不正确的参数并且可以修复它。

回答by Lucio

ECMAScript 6

ECMAScript 6

// @param callback Default value is a noop fn.
function save(callback = ()=>{}) {
   // do stuff...
   callback();
}

回答by Thank you

Rather than make the callback optional, just assign a default and call it no matter what

与其将回调设为可选,只需分配一个默认值并无论如何调用它

const identity = x =>
  x

const save (..., callback = identity) {
  // ...
  return callback (...)
}

When used

使用时

save (...)              // callback has no effect
save (..., console.log) // console.log is used as callback

Such a style is called continuation-passing style. Here's a real example, combinations, that generates all possible combinations of an Array input

这种风格被称为continuation-passing style。这是一个真实的例子,combinations它生成一个数组输入的所有可能的组合

const identity = x =>
  x

const None =
  Symbol ()

const combinations = ([ x = None, ...rest ], callback = identity) =>
  x === None
    ? callback ([[]])
    : combinations
        ( rest
        , combs =>
            callback (combs .concat (combs .map (c => [ x, ...c ])))
        )

console.log (combinations (['A', 'B', 'C']))
// [ []
// , [ 'C' ]
// , [ 'B' ]
// , [ 'B', 'C' ]
// , [ 'A' ]
// , [ 'A', 'C' ]
// , [ 'A', 'B' ]
// , [ 'A', 'B', 'C' ]
// ]

Because combinationsis defined in continuation-passing style, the above call is effectively the same

因为combinations是在 continuation-passing 风格中定义的,所以上面的调用实际上是相同的

combinations (['A', 'B', 'C'], console.log)
// [ []
// , [ 'C' ]
// , [ 'B' ]
// , [ 'B', 'C' ]
// , [ 'A' ]
// , [ 'A', 'C' ]
// , [ 'A', 'B' ]
// , [ 'A', 'B', 'C' ]
// ]

We can also pass a custom continuation that does something else with the result

我们还可以传递一个自定义的延续,它对结果做其他事情

console.log (combinations (['A', 'B', 'C'], combs => combs.length))
// 8
// (8 total combinations)

Continuation-passing style can be used with surprisingly elegant results

可以使用连续传递风格获得令人惊讶的优雅结果

const first = (x, y) =>
  x

const fibonacci = (n, callback = first) =>
  n === 0
    ? callback (0, 1)
    : fibonacci
        ( n - 1
        , (a, b) => callback (b, a + b)
        )
        
console.log (fibonacci (10)) // 55
// 55 is the 10th fibonacci number
// (0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...)

回答by G. Moore

A valid function is based on the Function prototype, use:

有效的函数基于函数原型,使用:

if (callback instanceof Function)

to be sure the callback is a function

确保回调是一个函数

回答by Malvolio

I got so tired of seeing that same snippet over and over I wrote this:

我厌倦了一遍又一遍地看到同样的片段,我写了这个:

  var cb = function(g) {
    if (g) {
      var args = Array.prototype.slice.call(arguments); 
      args.shift(); 
      g.apply(null, args); 
    }
  };

I've got hundred of functions doing things like

我有数百个函数可以做这样的事情

  cb(callback, { error : null }, [0, 3, 5], true);

or whatever...

管他呢...

I'm skeptical of the whole "make sure it's function" strategy. The only legitimate values are a function or falsy. If someone passes in a non-zero number or a non-empty string, what are you going to do? How does ignoring the problem solve it?

我对整个“确保它的功能”策略持怀疑态度。唯一合法的值是函数或假值。如果有人传入一个非零数字或非空字符串,你会怎么做?忽略问题如何解决问题?

回答by henry.oswald

I have sinced moved to coffee-script and found default arguments is a nice way to solve this problem

我已经转向咖啡脚本,发现默认参数是解决这个问题的好方法

doSomething = (arg1, arg2, callback = ()->)->
    callback()

回答by zVictor

It can easilly be done with ArgueJS:

它可以easilly可以用做ArgueJS

function save (){
  arguments = __({callback: [Function]})
.....do stuff......
  if(arguments.callback){
    callback();
  };
};

回答by Mrchief

If the criteria for running the callback is that whether its defined or not, then you're fine. Also, I suggest to check if its really a function in addition.

如果运行回调的标准是它是否定义,那么你没问题。另外,我建议检查它是否真的是一个功能。