メソッドをすぐに実行してからタイマーで実行するようにjavascriptのsetInterval
メソッドを設定する方法があります
初めて関数を直接自分で呼び出すのが最も簡単です。
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);
})();
これは機能を定義し、一度にすべてのサイクルを開始します。
私があなたを正しく理解しているかどうかはわかりませんが、次のようなことを簡単に行うことができます。
setInterval(function hello() {
console.log('world');
return hello;
}(), 5000);
これを行うには明らかにいくつもの方法がありますが、それが私が考えることができる最も簡潔な方法です。
私は同じ問題のためにこの質問に出くわしましたがsetInterval()
のように正確に振る舞う必要な場合には答えはどれも役に立ちませんが、only違いはすぐに呼び出されるということです。始まりです。
これがこの問題に対する私の解決策です:
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);
}
それでも、上記のすべての利点がここでも適用されますが、代替は必要ありません。
その振る舞いを提供する関数で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
デコレータ を使うことを検討してください。
// 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);
次の順序で関数を呼び出すことをお勧めします
var _timer = setInterval(foo, delay, params);
foo(params)
特定の条件でclearInterval(_timer)
を使いたい場合、_timer
をfooに渡すこともできます。
var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);
firstInterval という便利なnpmパッケージがあります(完全な開示、私のものです)。
ここに挙げた例の多くはパラメータ処理を含んでいません、そしてどんな大規模プロジェクトでもsetInterval
のデフォルトの振る舞いを変えることは悪です。ドキュメントから:
このパターン
setInterval(callback, 1000, p1, p2);
callback(p1, p2);
と同じです
firstInterval(callback, 1000, p1, p2);
あなたがブラウザの古い学校で依存関係を望まないのなら、それは コードからの簡単なカットアンドペーストです。
これは初心者向けの簡単なバージョンです。それは単に関数を宣言し、それを呼び出してから間隔を開始します。それでおしまい。
//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 );
この問題を解決するために、ページが読み込まれた後に初めて関数を実行します。
function foo(){ ... }
window.onload = function() {
foo();
};
window.setInterval(function()
{
foo();
}, 5000);