setInterval vs setTimeout

12月連続記事企画の5日目です。
今日は画面を作る時の話、JavaScript の話を書いてみたいと思います。

画面を更新する

さきラボの Web 表示器は、普通の Web 技術で画面を作ります。画面の更新は JavaScript で実装します。PLC のデータは API 経由で取得できるようになっています。

では早速、画面を更新するコードの例を書いてみましょう。昨日に引き続き、エラー処理は省略しています。

function update() {
    var req = [{ "method": "read", "addr": "ZR300", "len": 5 }];
    var param = { driver: "MELSEC-MX", station: 0, requests: req };
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "/api/plcComm", true);
    xhr.onload = function () {
        var res = JSON.parse(xhr.response).responses;
        // PLC のデータは配列になっている 例: [2017, 12, 5, 23, 19]
        document.body.innerText = res[0].data.toString();
    }
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.timeout = 500;
    xhr.send(JSON.stringify(param));
}

document.addEventListener("DOMContentLoaded", function () {
    setInterval(update, 100); // 10 FPS で画面を更新するのだ!
});

上記の実装には大きな問題があります。

API の応答速度は、実装方法や PLC の性能などによって違ってきます。例えば、昨日の記事で紹介した「PHP + MX Component」の場合、普通に実装すると応答時間が 100ms を超えてしまいます。ここで 100ms 周期の更新処理を実行した場合、API への多重リクエストが発生するため、通信エラーが発生します。

画面を "丁寧に" 更新する

通信エラーを回避するためには、以下のような実装が必要です。

function update() {
    var req = [{ "method": "read", "addr": "ZR300", "len": 5 }];
    var param = { driver: "MELSEC-MX", station: 0, requests: req };
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "/api/plcComm", true);
    xhr.onload = function () {
        var res = JSON.parse(xhr.response).responses;
        // PLC のデータは配列になっている 例: [2017, 12, 5, 23, 19]
        document.body.innerText = res[0].data.toString();
        setTimeout(update, 50); // 50ms 後に画面の更新を再実行する
    }
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.timeout = 500;
    xhr.send(JSON.stringify(param));
}

document.addEventListener("DOMContentLoaded", function () {
    update(); // 画面の更新を開始する
});

最初のコードから変更した部分に下線をひいてみました。

こちらの方法であれば、画面の更新 (PLC との通信) は「API との通信が終わってから 50ms 後」となります。これで、表示器が1台の環境であれば、多重リクエストは発生しなくなりました。

しかし、このままでは通信エラーが発生しただけで画面の更新が止まってしまいます。画面の更新を止めないようにするためには、エラー処理が必要です。明日はそのエラー処理について書いてみたいと思います。

この記事の投稿者

崎 洋佑
崎 洋佑プログラマーもどき
さきラボの代表取締役。自称プログラマーもどき。
開発でよく使う言語は日本語。
IT技術よりも人が好きな、天然物のエンジニアです。

setInterval vs setTimeout” に対して1件のコメントがあります。

コメントは受け付けていません。