37290


**何らかの終了処理判定する際、  
・setInterval(の一番短い間隔10ミリ秒)で監視継続し、  
・条件分岐がtrueになった所で、clearInterval実行して終了、  
という流れを考えているのですが、**

[code]

    var id = setInterval(function(){
      if(条件分岐){
          clearInterval(id);
      }
    }, 10);
    
[/code]

* * *

**Q1.こういうやり方をしても良いでしょうか？**  
・setIntervalは本来、アニメーションなどで繰り返し処理をするためのもの？  
・目的外使用？

* * *

**Q2.監視目的でsetIntervalを使用することのデメリットは？**  
・trueになるまで確認しつづける、ということは、ブラウザに負担がかかる、ということでしょうか？  
・ユーザがそのページを見る際、ブラウザ動作が重くなることがあり得る？  
・負担があるとすれば、実行間隔よりも、繰り返し処理する内容に依存する？？


CC BY-SA 3.0
2017-08-17T12:53:17.857
37287
2017-08-17T14:36:01.153
7886
question
javascript
監視目的でsetIntervalを使用しても良い？


そういった目的に `setInterval()` を使用しても構いませんが、

  * とうぜん、約「実行回数 × 処理内容」のCPUコストがかかります。ブラウザのプロセスが重くなるかもしませんし、OS 全体が重くなるかもしれませんし、バッテリーの消費が増えるかもしれません。

  * 自身の管理下にあるコードでの状態変化を監視するのなら、通常は `setInterval()` はいらないはずです。オブザーバパターンなどが役に立ちます。

何を監視して何をしたいのかを書いたほうがより良い回答が得られるのではないかと思います。たとえば、DOMの変更を監視したいなら`MutationObserver`が最適な手段かもしれません。


CC BY-SA 3.0
2017-08-17T13:51:31.823
37290
2017-08-17T13:51:31.823
3475
37287
answer


# 連続処理

基本的に、コードは書いた順番で実行されます。

[code]

    console.log('start');
    console.log('execute');
    console.log('end');
    
[/code]

このコードは期待通り、「start -> execute -> end」の順番で実行されます。  
この時、コードを関数化して別の場所に置きたい場合もあるでしょう。  
その場合も関数を順番通りに呼び指せば、期待通りに機能します。

[code]

    start();
    execute();
    end();
    
[/code]

ところが、ここで **非同期処理** を挟むと期待通りの順番で実行されません。

[code]

    console.log('start');
    fetch('./').then(response => console.log('execute'));
    console.log('end');
    
[/code]

このコードは、「start -> end -> execute」の順番で出力されます。  
非同期処理の順番を制御する方法はいくつかあります。

# コールバック関数

一つは、コールバック関数を定義してやることです。  
非同期処理を実行する関数の最後でコールバック関数を呼び出す事で外部から終了処理を与えることが出来ます。

[code]

    function start () {
      console.log('start');
    }
    
    function execute (end) {
      fetch('./').then(response => {console.log('execute');end();});
    }
    
    function end () {
      console.log('end');
    }
    
    start();
    execute(end);
    
[/code]

# Promise

コールバック関数を発展させたものが `Promise` です。  
Promise は統一されたインターフェースでコールバック関数を制御することが出来ます。  
**Fetch API** は Promise を返すので、そのまま利用することが出来ます。

[code]

    function start () {
      console.log('start');
    }
    
    function execute (end) {
      fetch('./').then(response => (console.log('execute'),this)).then(end);
    }
    
    function end () {
      console.log('end');
    }
    
    start();
    execute(end);
    
[/code]

# DOM Events

DOM Events も非同期処理の一つです。  
独自のイベントを定義してやる事で終了処理を呼び出すことが出来ます。

[code]

    function start () {
      console.log('start');
    }
    
    document.addEventListener('custom-end', function (event) { console.log(event.type); }, false)
    
    function execute () {
      fetch('./').then(response => (console.log('execute'), document.dispatchEvent(new Event('custom-end'))));
    }
    
    start();
    execute();
    
[/code]

ただし、DOM Events はDOMと密接にかかわる非同期処理で効果を発揮します。  
必要もないのに、DOMノードでイベントを発火させるのはグローバル変数を作るのと同じなので避けた方が良いでしょう。

Re: @re9


CC BY-SA 3.0
2017-08-17T14:36:01.153
37292
2017-08-17T14:36:01.153
20262
37287
answer