回答:
初めて関数を自分で直接呼び出すのが最も簡単です。
foo();
setInterval(foo, delay);
ただし、回避するのには十分な理由があります。setInterval
特に状況によっては、setInterval
イベントの負荷全体が遅延なしでお互いの直後に到着する場合があります。もう1つの理由は、ループを停止する場合は明示的に呼び出すclearInterval
必要があるためsetInterval
です。つまり、元の呼び出しから返されたハンドルを覚えておく必要があります。
したがって、代わりの方法は、代わりfoo
に次の呼び出しを使用して自身をトリガーすることですsetTimeout
。
function foo() {
// do stuff
// ...
// and schedule a repeat
setTimeout(foo, delay);
}
// start the cycle
foo();
これにより、少なくともdelay
呼び出しの間に間隔があることが保証されます。また、必要に応じてループをキャンセルするのも簡単になりsetTimeout
ます。ループの終了条件に達したときに呼び出さないだけです。
さらに良いのは、すぐに呼び出される関数式ですべてをラップして、関数を作成し、上記のように再度呼び出してループを自動的に開始することです。
(function foo() {
...
setTimeout(foo, delay);
})();
関数を定義し、サイクルをすべて一度に開始します。
setTimeout
ですか?
setInterval
イベントが遅延なしでお互いの直後に到着する場合があります。
setTimeout
メソッドを使用する場合、関数を停止するにはどうすればよいですか?
私があなたを正しく理解しているかどうかはわかりませんが、次のようなことは簡単にできます。
setInterval(function hello() {
console.log('world');
return hello;
}(), 5000);
これを行う方法はいくつもありますが、それが私が考えることができる最も簡潔な方法です。
arguments.callee
はES5ストリクトモードでは使用できません
同じ問題が原因でこの質問に出くわしましたが、まったく同じように動作する必要がある場合、どの回答も役に立ちませんが、最初に関数がすぐに呼び出されるという唯一の違いがあります。setInterval()
これがこの問題に対する私の解決策です:
function setIntervalImmediately(func, interval) {
func();
return setInterval(func, interval);
}
このソリューションの利点:
setInterval
、置換によって簡単に適合させることができますclearInterval()
後で渡すことができます例:
// create 1 second interval with immediate execution
var myInterval = setIntervalImmediately( _ => {
console.log('hello');
}, 1000);
// clear interval after 4.5 seconds
setTimeout( _ => {
clearInterval(myInterval);
}, 4500);
生意気であるために、本当に使用する必要がある場合setInterval
は、元のを置き換えることもできますsetInterval
。したがって、既存のコードの前にこれを追加する場合、コードを変更する必要はありません。
var setIntervalOrig = setInterval;
setInterval = function(func, interval) {
func();
return setIntervalOrig(func, interval);
}
それでも、上記のすべての利点がここに適用されますが、代用する必要はありません。
setTimeout
返すため、私はソリューションよりもこのソリューションを好みsetInterval
ます。多分、後のコードで、したがって、現在の時点で未定義の関数を呼び出す避けるために、私は最初の関数呼び出しラップsetTimeout
:このような機能setTimeout(function(){ func();},0);
最初の関数は、現在の処理サイクル後に呼び出され、またあるすぐに、しかしですより多くのエラーが証明されました。
setInterval()
その振る舞いを提供する関数でラップすることができます:
function instantGratification( fn, delay ) {
fn();
setInterval( fn, delay );
}
...その後、次のように使用します。
instantGratification( function() {
console.log( 'invoked' );
}, 3000);
ここに、必要に応じてそれをきれいにするラッパーがあります:
(function() {
var originalSetInterval = window.setInterval;
window.setInterval = function(fn, delay, runImmediately) {
if(runImmediately) fn();
return originalSetInterval(fn, delay);
};
})();
setIntervalの3番目の引数をtrueに設定すると、setIntervalを呼び出した直後に初めて実行されます。
setInterval(function() { console.log("hello world"); }, 5000, true);
または、3番目の引数を省略すると、元の動作が保持されます。
setInterval(function() { console.log("hello world"); }, 5000);
一部のブラウザーは、このラッパーが考慮しないsetIntervalの追加の引数をサポートしています。これらはめったに使用されないと思いますが、必要な場合は覚えておいてください。
this
まるでそれが矢の関数であるかのように誰かが外側を内側に持ってくる必要があるからです。
(function f() {
this.emit("...");
setTimeout(f.bind(this), 1000);
}).bind(this)();
上記の生成ゴミが気になる場合は、代わりにクロージャーを作成できます。
(that => {
(function f() {
that.emit("...");
setTimeout(f, 1000);
})();
})(this);
または、コードに応じて、@autobind
デコレータの使用を検討してください。
次の順序で関数を呼び出すことをお勧めします
var _timer = setInterval(foo, delay, params);
foo(params)
特定の条件で行い_timer
たい場合は、fooに渡すこともできclearInterval(_timer)
ます
var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);
これは、すべての混乱のない初心者向けのシンプルなバージョンです。関数を宣言して呼び出し、間隔を開始するだけです。それでおしまい。
//Declare your function here
function My_Function(){
console.log("foo");
}
//Call the function first
My_Function();
//Set the interval
var interval = window.setInterval( My_Function, 500 );
firstIntervalと呼ばれる便利なnpmパッケージがあります(完全な開示、私のものです)。
ここでの例の多くにはパラメータ処理が含まれておらず、setInterval
大規模なプロジェクトでのデフォルトの動作を変更することは悪いことです。ドキュメントから:
このパターン
setInterval(callback, 1000, p1, p2);
callback(p1, p2);
と同じです
firstInterval(callback, 1000, p1, p2);
// YCombinator
function anonymous(fnc) {
return function() {
fnc.apply(fnc, arguments);
return fnc;
}
}
// Invoking the first time:
setInterval(anonymous(function() {
console.log("bar");
})(), 4000);
// Not invoking the first time:
setInterval(anonymous(function() {
console.log("foo");
}), 4000);
// Or simple:
setInterval(function() {
console.log("baz");
}, 4000);
これはとても複雑なので、もっと簡単に説明しましょう。
function hello(status ) {
console.log('world', ++status.count);
return status;
}
setInterval(hello, 5 * 1000, hello({ count: 0 }));
非常に小さい初期遅延時間(たとえば100)を設定し、関数内で希望の遅延時間に設定できます。
var delay = 100;
function foo() {
console.log("Change initial delay-time to what you want.");
delay = 12000;
setTimeout(foo, delay);
}
関数の即時非同期呼び出しには問題があります。標準のsetTimeout / setIntervalは、直接0に設定した場合でも、数ミリ秒程度の最小タイムアウトがあるためです。これは、ブラウザー固有の作業が原因です。
Chrome、Safari、Operaで動作するREALゼロ遅延のコードの例
function setZeroTimeout(callback) {
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage('');
}
あなたはここでより多くの情報を見つけることができます
また、最初の手動呼び出しの後、関数を使用して間隔を作成できます。
実際には最速のことです
interval = setInterval(myFunction(),45000)
これはmyfunctionを呼び出し、それから45秒ごとに再びそれを実行します。
interval = setInterval(myfunction, 45000)
それは呼ばれませんが、それだけをスケジュールします
myFunction()
は、それ自体が戻る場合のみです。代わりに、setInterval
それによって呼び出されるように各関数を変更することはsetInterval
、他の回答が提案しているように一度ラップするより良いアプローチです。
function
一度電話をかけ、それからsetInterval()