web-dev-qa-db-ja.com

setInterval()を使用して単純な連続ポーリングを行う

設定された間隔でユーザーに提示されるデータの一部を更新する必要がある単純なWebアプリの場合、適切なポーリングフレームワークを使用する代わりに、setInterval()を使用してエンドポイントからJSONを取得するだけの欠点はありますか?

例のために、5秒ごとに処理ジョブのステータスを更新するとします。

31
Sologoub

私のコメントから:

setTimeoutを使用します[ドキュメント] そして、前の応答が受信されたときに常に呼び出します。この方法により、要求/応答が間隔よりも長くかかる場合に、輻輳や関数のスタッキングなどを呼び出すことを回避できます。

だからこのようなもの:

function refresh() {
    // make Ajax call here, inside the callback call:
    setTimeout(refresh, 5000);
    // ...
}

// initial call, or just call refresh directly
setTimeout(refresh, 5000);
51
Felix Kling

Promisesを使用して、最近のブラウザーに単純な非ブロッキングポーリング機能を実装できます。

var sleep = time => new Promise(resolve => setTimeout(resolve, time))
var poll = (promiseFn, time) => promiseFn().then(
             sleep(time).then(() => poll(promiseFn, time)))

// Greet the World every second
poll(() => new Promise(() => console.log('Hello World!')), 1000)
10
bschlueter

次のようにできます:

var i = 0, loop_length = 50, loop_speed = 100;

function loop(){
    i+= 1; 
    /* Here is your code. Balabala...*/
    if (i===loop_length) clearInterval(handler);
}

var handler = setInterval(loop, loop_speed);
2
Scen

私はこれが古い質問であることを知っていますが、つまずいたので、StackOverflowのやり方で改善できると思いました。 ここで説明しているもの に似たソリューションを検討することをお勧めします。これはロングポーリングとして知られています。 OR別のソリューションはWebSockets(すべてのブラウザで動作することを主な目的とするwebsocketsのより良い実装の1つ) socket.io です。

最初のソリューションは基本的に、単一のAJAXリクエストを送信し、追加のリクエストを送信する前に応答を待機し、応答が配信されたら次のクエリをキューに入れるように要約されます。

一方、バックエンドでは、ステータスが変更されるまで応答を返しません。したがって、シナリオでは、ステータスが変更されるまで継続するwhileループを利用し、変更されたステータスをページに返します。私はこのソリューションが本当に好きです。上記のリンクの答えが示すように、これはfacebookが行うことです(または少なくとも過去に行ったことです)。

socket.ioは基本的にWebsocketのjQueryであるため、ユーザーがどのブラウザーにいても、ページにデータをプッシュできる(ポーリングをまったく行わない)ソケット接続を確立できます。これは、Blackberryのインスタント通知に近いものです。インスタント通知を使用する場合は、これが最適なソリューションです。

1
th3byrdm4n