2

特定の長時間実行機能を備えたサードパーティのJavaScriptライブラリを使用しています(ネットワークを介したWebサービス呼び出しなどが含まれます)。簡単にするために、1つのパラメーター、つまり長時間実行操作が完了したときに呼び出すコールバック関数が必要であるとしましょう。したがって、署名があるとしますlongRunningFunction(callback)

残念ながら、この関数は「コンテキスト」パラメータを受け入れないため、longRunningFunction複数回呼び出すと、コールバックが呼び出されたときに、どの呼び出しがどのコールバックにつながったかを知る方法がありません。

これを解決するには、無名関数を使用して次の方法を見つけました。関数を定義しmycallback(context)、長時間実行する操作を呼び出すたびに次のようなことを行います。

uniqueContext = getUniqueContextFromSomewhere();
longRunningFunction(function() {mycallback(uniqueContext)});

これは機能するようですが、私の質問は、長時間実行操作が別のスレッドで実行されている可能性があることを考えると、JavaScript仕様に従って動作することが保証されているかどうかです。これにより、longRunningFunctionへのさまざまな呼び出しへのコールバックが発生する可能性があります。それで、私が見つけた解決策は有効ですか?

4

2 に答える 2

2

このコードを仮定すると:

function longRunningFunction( fn ) {
    window.setTimeout( fn, 1000 ); // just to make it async
}

function myCallback( context ) {
    /* ... */
}

これがあれば:

var uniqueContext = getUniqueContext( );
longRunningFunction( function ( ) { myCallback( uniqueContext ); } );

contextのパラメータは、コールバックが発生する瞬間にmyCallbackなることが標準で指定されています。ループでこのようなことを試みると、いくつかの問題が発生する可能性があります (反復ごとに消去するため)。uniqueContext uniqueContext

これを行う場合:

var uniqueContext1 = getUniqueContext1( );
longRunningFunction( function ( ) { myCallback( uniqueContext1 ); } );

var uniqueContext2 = getUniqueContext2( );
longRunningFunction( function ( ) { myCallback( uniqueContext2 ); } );

を使用するコールバックは、最初の終了uniqueContext1時に呼び出され、2 番目の終了時に使用されるコールバックが保証されます (以前と同じ制限があります。スコープ内のどこかを上書きすると、コールバック パラメータも変更されます)。longRunningFunctionuniqueContext2longRunningFunctionuniqueContext1uniqueContext2

bind を使用すると、クロージャー (および前述のデフォルト) の作成を回避できます。次のコードは前のコードと似ていますが、前のコードを上書きして誤ってパラメーターの値を変更することはできません。

longRunningFunction( mycallback.bind( null, getUniqueContext1( ) ) );
longRunningFunction( mycallback.bind( null, getUniqueContext2( ) ) );

mycallback.bind( null, someParameter )は、呼び出されたときにmycallbackas null(通常の関数のようthisにフォールバックします) および最初のパラメーターとして呼び出される関数を返します。windowsomeParameter

bindもう1つの答えは、変数を使用するための最初のパラメーターのみを使用するthisことですが、必須ではなく、代わりに関数パラメーターを安全に使用できます。

于 2013-02-05T02:22:31.420 に答える