私は時々コールバックを受け取り、それを実行するいくつかの関数を持っています。コールバックが定義/機能されているかどうかを確認するのは良いスタイルですか、それとももっと良い方法がありますか?
例:
function save (callback){
.....do stuff......
if(typeof callback !== 'undefined'){
callback();
};
};
私は個人的に好む
typeof callback === 'function' && callback();
typeof
コマンドは危険ですが、"undefined"
および"function"
にのみ使用する必要があります
typeof !== undefined
の問題は、ユーザーが定義された値を渡す可能性があることです関数ではない
次のこともできます。
var noop = function(){}; // do nothing.
function save (callback){
callback = callback || noop;
.....do stuff......
};
callback
をいくつかの場所で使用する場合に特に役立ちます。
さらに、jQuery
を使用している場合、すでにそのような関数があります。これは $。noop と呼ばれます
単純に
if (callback) callback();
タイプが何であれ、コールバックが提供されている場合はコールバックを呼び出すことを好みます。黙って失敗させないようにしてください。実装者は間違った引数を渡したことを認識し、修正できます。
// @param callback Default value is a noop fn.
function save(callback = ()=>{}) {
// do stuff...
callback();
}
コールバックをオプションにするのではなく、デフォルトを割り当てて、それが何であれそれを呼び出すだけです
const identity = x =>
x
const save (..., callback = identity) {
// ...
return callback (...)
}
使用するとき
save (...) // callback has no effect
save (..., console.log) // console.log is used as callback
このようなスタイルは 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' ]
// ]
combinations
は継続渡しスタイルで定義されているため、上記の呼び出しは事実上同じです
combinations (['A', 'B', 'C'], console.log)
// [ []
// , [ 'C' ]
// , [ 'B' ]
// , [ 'B', 'C' ]
// , [ 'A' ]
// , [ 'A', 'C' ]
// , [ 'A', 'B' ]
// , [ 'A', 'B', 'C' ]
// ]
また、結果に対して何か他のことをするカスタム継続を渡すこともできます
console.log (combinations (['A', 'B', 'C'], combs => combs.length))
// 8
// (8 total combinations)
継続渡しスタイルを使用して驚くほどエレガントな結果を得ることができます
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, ...)
同じスニペットを何度も何度も見るのにうんざりしました。
var cb = function(g) {
if (g) {
var args = Array.prototype.slice.call(arguments);
args.shift();
g.apply(null, args);
}
};
私は次のようなことをする関数を何百も持っています
cb(callback, { error : null }, [0, 3, 5], true);
または何でも...
私は「それが機能していることを確認する」戦略全体に懐疑的です。唯一の正当な値は、関数または偽です。誰かがゼロ以外の数字または空でない文字列を渡すと、どうしますか?問題を無視することでどのように解決しますか?
有効な関数は、Functionプロトタイプに基づいています。以下を使用します。
if (callback instanceof Function)
コールバックが関数であることを確認する
コールバックを実行するための基準が、定義されているかどうかにかかわらず、大丈夫です。また、実際に機能するかどうかも確認することをお勧めします。
ArgueJS で簡単に行えます:
function save (){
arguments = __({callback: [Function]})
.....do stuff......
if(arguments.callback){
callback();
};
};
私はコーヒースクリプトに移行して以来、デフォルトの引数がこの問題を解決する良い方法であることがわかりました
doSomething = (arg1, arg2, callback = ()->)->
callback()