Abstract: This Javascript function will execute specific code when specific condition is met.  It accepts two arguments, check fuction and proc function, and executes the proc() only when check() return true through window.setInterval mechanism.

這是我蠻常遇到的需求:

持續檢查網頁(甚至另一個Frame)裡某個元素、物件或變數的狀態,當符合某項條件時,觸發某段程式。

要精準地掌握狀態改變時機,最好的方法是透過onchage、onclick等事件即時觸發,但有些時候,"狀態"是指某個Javascrip Boolean變數,而該變數可能被多個來源修改。與其找出所有修改源頭去掛事件,還不如採用定時Polling的做法讓機制簡化,較不容易出錯。(我算是KISS準則的忠實擁護者,Keep It Simple and Stupid!)

利用setInterval定期檢查,執行完clearInterval的技巧以前就用過了,今天特地把它包成一個獨立函數delayExecute,在此列出程式與應用範例以饗同好!

//Parameters:
//check      : a function to return true/false
//proc       : a function which won't run until check() return true
//chkInterval: optional, checking interval, default value is 500ms
function delayExecute(check, proc, chkInterval) {
    //default interval = 500ms
    var x = chkInterval || 500;
    var hnd = window.setInterval(function () {
        //if check() return true, 
        //stop timer and execute proc()
        if (check()) {
            window.clearInterval(hnd);
            proc();
        }
    }, x);
}
delayExecute(
  function() { 
    return document.getElementById("txtTest").value == "OK";
  }, 
  function() {
    alert("Executed!");
  }
); 

Comments

# by jaceju

如果用 jQuery 的話,是不是可以用 bind + trigger 的方式?

# by Jeffrey

to jaceju, 是指自訂特別的事件,再由程式去觸發嗎? 這樣子似乎還是會受限於當改變狀態的來源有多個時,就得調整各來源更動狀態的寫法,由原本修改某個Javascript變數變成trigger某個特定物件的事件,修改幅度較大。另外還有一些情境是狀態變化的來源是沒有能力主動回報(例如: 某個外部的js,我們無權更動其邏輯),我想這類場合用Polling來解就挺不賴的。

# by Ives

如果想監測的是 「某個 api 回傳不同的json,循環n次」 當這n個 json回傳完畢才執行下一段程式, 請問該怎麼作呢?

# by Jeffrey

to Ives, 我會這麼做: "當這n個 json回傳完畢時設window.finishFlag = true", check = function() { return window.finishFlag == true; },不知是否符合你的需求?

# by Ives

謝謝!這應該能解決我的問題,謝謝!! 另外想請問 check = function() { return window.finishFlag == true; } 這一段程式中的function 是不是要設為 Interval ,格一段時間就檢查,直到確定傳回true才終止呢?

# by Jeffrey

to Ives, delayExecute()這個函數就是在做"隔一段時間就檢查check(),直到確定傳回true就執行proc()程式並終止"。

# by Ives

了解,謝謝。

Post a comment