2016-12-06 17 views
1

ここで関数を呼び出すことは、コードの一部です:私はこの奇妙な状況があるJavascriptが:一度だけ

if (lastPosition == 0) { 
    callsomemethod(param); 
} 

、私は関数callsomemethod(パラメータ)を呼び出す必要が特徴。 if条件が2回以上真であったとしても。言い換えれば、関数callomemethodがif文が複数回trueであっても1度だけコールされるようにしたいのです。 if文の中にはもっと多くのことがありますが、私は単純化のためにそれらを取り出しています。

編集:すべての応答ありがとうございます。残念ながら、ifステートメントは関数内にあり、その関数が複数回呼び出されてすべてが再び初期化されるため、アプローチのいずれも機能しません。また、この関数はIIFEの内部にあります。最初のショットですべてをクリアにしないことに対する謝罪。事前

+0

置き換えますか? 'callmemethod = function(){};' –

+0

私は、メソッドを呼び出すときに真となるif文をチェックインする 'methodcalled'フィールドを追加するのが最も簡単な方法でしょう。あなたはそれをやっていない理由はありますか? – Robba

答えて

5

これを行うための慣用的な方法で

おかげで、必要に応じて閉鎖を経由して隠されたロック変数、です。最も単純な例は次のようになります(...args構文は古いブラウザでは動作しないことがあり

function wrapOnce(fn) { 
    var done = false; 
    return function (...args) { 
    if (!done) { 
     done = true; 
     return fn.apply(this, args); 
    } 
    } 
} 

var done = false; 
function callOnce(lastPosition) { 
    if (lastPosition == 0 && !done) { 
    done = true; 
    callSomeMethod(lastPosition); 
    } 
} 

は一度だけ呼び出すことができ機能、あなたはクロージャを使用して、それをラップすることができますを生成しますargumentsを確認し、簡略化のために省略したコードに置き換える必要があります)

これはlodash's onceのようなヘルパーの基礎です。

はJSでのみアクセス変数に単一のスレッドを可能にするので、これは本質的にスレッドセーフな(それが適用されるような)であり、複数のコールバックがonce -ifiedメソッドを使用しようとすると、中断されません。

+0

スプレッド演算子、 '...'は、目に見えて古いブラウザでは利用できないES6の1つです。 – Ouroborus

+0

@Ouroborus私は認識しています(そして答えにメモを追加します)。これは、例をはるかに読みやすくするだけです。 – ssube

2

機能が以前か呼び出された場合に追跡するためのフラグを追加します。

var wasCalled = false; 

// ... 

if (lastPosition == 0) { 
    if(!wasCalled) { 
    wasCalled = true; 
    callsomemethod(param); 
    } 
} 

より高度な、全体を包むために閉鎖を活用する:

var callsomemethod = (function(){ 
    var wasCalled = false; 
    return function(param){ 
    if(wasCalled){ 
     return; 
    } 
    else { 
     wasCalled = true; 
    } 
    // callsomemethod()'s inner code goes here 
    }; 
})(); 
+1

複数のコールサイトでは、callsomemethod()の内部にロジックを配置します。 –

0

は、グローバル変数を宣言var ran = false、callsomethingmethodの中でtrueに設定してください。

0

あなたは、ブール値は、メソッドを初めて呼び出すときにtrueに設定されているcalled呼ばれている可能性:ここで

var called = false; 
if (lastPosition == 0) { 
    if(!called){ 
    callsomemethod(param); 
    called = true; 
    } 
} 
0

が前の回答にはまだ似た別の方法です。呼び出し時動作を追加するには関数プロトタイプを使用できます。以下のコードでは、最初の呼び出しだけが結果を出力します。

function callSomeMethod(param){ 
    console.log('called...'+param); 
}; 

Function.prototype.onlyOnce = function(param){ 
    if(!this.wasCalled && this == callSomeMethod){ 
    this(param); 
    this.wasCalled = true; 
    } 
}; 


function outerMethod(){ 
    callSomeMethod.onlyOnce('foo'); 
    callSomeMethod.onlyOnce('bar'); 
} 

outerMethod();