2016-05-05 11 views
2

のNode.jsとBluebird.jsを使用し、特定のプロジェクトで作業するとき、私は多くの場合、次のアプローチを参照してください。`.then`ハンドラで不要なラッパー関数を削除しますか?

function someAsyncOp(arg) { 
    return somethingAsync(arg).then(function (results) { 
     return somethingElseAsync(results); 
    }); 
} 

これはまったく同じ引数を受け入れる別の関数のラッパー関数/クロージャを作成する、です。

function someAsyncOp(arg) { 
    return somethingAsync(arg).then(somethingElseAsync); 
} 

私は他の人にそれを提案するとき、彼らは通常、それを好きでそれに切り替えます。

重要な注意点は、しかし、があります:(のようなconsole.logはありません)あなたがobject.functionのようなものを呼んでいる、と関数がthisに依存している場合は、thisは、その結合を失うことになります。

return somethingAsync(arg).then(somethingElseAsync).catch(console.log.bind(console)); 

これは潜在的に望ましくないようです、と.bindコールは少しぎこちない感じている:あなたはobject.function.bind(object)をしなければなりません。あなたはいつも閉鎖的なアプローチで間違って行くことはできません。

Googleでこれについての議論を見つけることはできませんが、不要なラッパー関数についてはESLintでは何もないようです。私はそれについてもっと知ろうとしていますのでここにいるのです。私はそれが私が私が知らないものを知らないのだと思います。 名前はありますか?(閉鎖の役に立たない使用?)他の考えや知恵?ありがとうございます。

:誰かが、someAsyncOpも冗長であるとコメントするつもりです。それは、何か役に立つとふりをしましょう。

答えて

2

ここでの説明はかなり簡単です。あなたの関数がpromiseシステムによって直接呼び出されている場合、正確な引数とthisの値は、promiseシステムによって直接呼び出され、その戻り値があなたが約束したいチェーンのものである場合ちょうど.then()ハンドラとして直接関数参照を指定する手段、:

somethingAsync(arg).then(somethingElseAsync) 

しかし、あなたの関数がそのように直接呼ばれるように設定されていない場合は、修正が.bind()のようなラッパー関数か何かを必要としますあなたが望むようにあなたの関数を正確に呼び出すか、適切な戻り値を設定してください。

それ以上のことはありません。 Javascriptのどこにでもコールバックを指定することと変わりありません。コールバックの仕様をすでに満たしている関数がある場合は、その関数名をラッパーのない直接参照として指定できます。しかし、あなたが持っている関数が、コールバックがうまく動作するように設計されていない場合は、ラッパー関数を使って不一致をスムーズにします。

すべてのコールバック関数には、コールバックとしてobj.methodを渡す際に同じ問題があります。 にの値がobjであると予想される場合は、関数が実行される前にの値が設定されているかどうかを確認する必要があります。 .then()ハンドラのコールバックは、setTimeout()またはfs.readFile()などの他のJavascript/node.js関数のコールバックや、コールバックを引数として受け取るその他の関数と同じです。だから、あなたが言及している問題のどちらも、約束にはまったくユニークではありません。コールバックを使ってメソッド呼び出しを行う場合、メソッドに適切に渡されたオブジェクト値で問題が実行されます。

FYIでは、独自のオブジェクトに永続的にバインドされ、obj.methodとして渡すことができるようにメソッドをコーディングすることはできますが、これはメソッドの実装でしか使用できず、その他のトレードオフがあります。一般的に経験豊富なJavascriptの開発者は、パスの参照としてobj.method.bind(obj)を使用して完全に細かいです。コード内の.bind()を見ると、メソッド内に適切なobj値が必要であり、そのための準備ができていることを認識していることを示しています。

ご太字の質問やコメントのいくつかについては:

は、このために名前はありますか?

私は認識していません。技術的には「名前付きリファレンスをコールバックとして以前に定義された関数に渡していますが、それはあなたが検索して役に立つディスカッションを見つけることのできるものではないでしょうか?

他の考えや知恵はありますか?理由から

、私は(他の場所で議論の話題となっているが)全くわからないんだけど、Javascriptのプログラミングスタイルの規則ではなく他の場所で、その後、メソッドまたは関数を定義するよりも、匿名のインラインコールバックの使用を奨励するように見えますその名前付きリファレンスを渡します(あなたが他の多くの言語で行う可能性が高いように)。明らかに、コールバックをインラインの匿名関数で処理する実際のコードを記述すると、あなたが言及した問題のどちらも現れません。 ES6の矢印機能を使用すると、インラインコールバックに現在の値thisを保存することもできます。私はこれがあなたの質問に対する答えであるということではありません。一般的なJavascriptのコーディング規則についての見解だけです。

let's-always-do-the-closureのアプローチでは間違ってはいけません。

既に知っているように、ラッピングする必要がなければ何かをラップするのは無駄です。コールバックの仕様と既存の名前付き関数の間に不一致があり、名前付き関数をコールバックの仕様に一致するように修正しない理由がある場合にのみ、折り返しに投票します。

関連する問題