[ 新規に投稿する ]

hidemaru.setIntervalとキューの問題をヘルプにNo.10534
こみやんま さん 25/02/01 04:42 [ コメントを投稿する ]
  「hidemaru.setInterval」と「モーダル系のブロック関数」と「キューの問題」をヘルプに記載した方が
よいかもしれないです。



一般のブラウザのJavaScriptの場合は、
完全な「重度のモーダル系のブロック関数」は window.alert 系しかないので
ほぼ問題にはなりませんが、

秀丸の場合は、「Bの実行空間で実行中のブロックモーダル関数(messageやinputや*dialog)」が
「全く異なる無関係なAの実行空間のhidemaru.setIntervalの実行に影響を与えてしまう」ため、
「setIntervalで指定したインターバル」に頼らず、
「実際の経過時間がそれなりに妥当なのかを判定するべき」
ということを記載したほうがよさそうです。


setIntervalの項目などに記載するのがいいのかな?


// --- とあるエンジン&実行空間でsetIntervalしているものとする。

jsmode "JScript\\aaa";
js {
debuginfo(2);
var i=1;

if (typeof(t) != "undefined") {
    console.log("前回のクリア");
    hidemaru.clearInterval(t);
}

var intervalTime = 500;

// 「実際の経過時間」がintervalTime に対して妥当ならtrue。そうでないならfalse;
var lastTime = 0;
function checkTimeElapsed() {
   var currentTime = tickcount();
   var elapsedTime = currentTime - lastTime; // 経過時間を計算
   console.log("経過:" + elapsedTime);

   if (elapsedTime >= intervalTime * 0.95) { // 0.95倍ぐらいのゆらぎなら許可
      lastTime = currentTime;
      return true; 
  } else {
      return false;
  }
}

debuginfo(2);
var t = hidemaru.setInterval(function() {

    // キューされて連続実行されているかもしれない、実際の経過時間をチェック
    var elapsed = checkTimeElapsed();
    if (!elapsed) {
        console.log("実間隔が短すぎる。スルーすべき"); return;
    }

    console.log("interval:" + i++);
    }, intervalTime);
}





// ----------------
// (同一プロセスで)全く違うマクロにて「ブロックモーダル系関数」を使ってしまったとする。

jsmode "WebView2\\bbb";
js {
    message("OK");
}


```
意表を付くことに、「全く無関係な、他の実行空間のものであったとしても」上記のsetIntervalの実関数は実行されず、予約キューだけがどんどん蓄積されてしまう。
この時、「同一プロセス上の全てのsetIntervalやsetTimeoutなどは実行されず」、予約キューとしてのみ蓄積される。
そして、ブロック(モーダル)関数の終了の直後に、それまで蓄積されていたキューが「一気に全て」実行されてしまう。
この時、(マクロ)作者が「Intervalで指定したものとは全く異なる非常に短い間隔で」関数が連続して実行されてしまうため、予期せぬ不具合をまねきやすい。


これを防止するためには、checkTimeElapsed のような「実際に時間は経過しているのか?」を判定するなり、なんなりする必要がある。

(=簡易サンプルならまだしも、実践のマクロでは「本当に時間が経過していること[もしくはさせること]を自前で担保する必要があるということ。)
```

的なことを軽くヘルプに触れておくだけでも気づきやすいかと。


[ ]
RE:10534 hidemaru.setIntervalとキューの問題をヘルプにNo.10535
秀丸担当 さん 25/02/03 13:57 [ コメントを投稿する ]
  ご指摘ありがとうございます。
確かにhidemaru.setIntervalはjs{}を抜けた後でないと実行されないようになっています。
ヘルプにも書いたほうがいいということで、ご意見参考にさせていただきます。
[ ]

[ 新規に投稿する ]