天天看點

閉包實作輪詢器的面試題

請實作以下功能: simplePoller

1.simplePoller 函數接受兩個參數:和 queryFn  callback
2.queryFn 是一個傳回或 true  false
3.callback 是在傳回時應調用的函數 queryFn  true

需求說明:
simplePoller應該定期調用 queryFn。
當傳回false時,它會等待一段時間,然後再次調用直到傳回 。
從1秒開始,每次呼叫之間的等待間隔每次增加1.5倍。
當傳回true時,調用并退出該函數。 
例如:
第一次:等待1秒
第二次:調用并傳回,等待1.5秒 queryFn  false
第三次:調用并傳回,等待2.25秒 queryFn  false
第4次:調用并傳回,執行并退出 queryFn  true callback 

確定通過以下測試用例:
simplePoller 應該在第一次調用之前等待1秒鐘。
queryFn等待間隔是前一個間隔的1.5倍,第一次間隔(1秒)除外。
simplePoller 應該允許同時調用,并且函數的調用不會互相幹擾。
           

正常方法:

// -------- 方法一 普通方法 -------------
// 時間間隔
var time = 1000,
    // 計數器
    num = 0;
// 定時器
timer = null;

function simplePoller_1(queryFn, callback) {
    if (queryFn()) {
        return callback()
    } else {
        timer = setTimeout(function() {
            clearInterval(timer);
            timer = undefined;
            console.log("調用" + num + "次,等待了" + time + "s");
            simplePoller_1(queryFn, callback);
            time = time * 1.5;
        }, time)
    }
}

function queryFn() {
    num++;
    if (num > 3) return true;
    return false;
}

function callback() {
    console.log("Success callback");
}
simplePoller_1(queryFn, callback)


           

方法二:閉包

function simplePoller_2() {
    // 初始時間間隔 1S
    var time = 1000,
        // 計數器 統計queryFn調用次數
        num = 0,
        // 定時器
        timer;
    return {
        simplePoller: function() {
            // 如果queryFn 傳回false 
            if (!this.queryFn()) {
                // 重新計時
                clearTimeout(timer);
                // 建立新的定時器去重新調用queryFn ,延遲為調用的次數*1.5
                timer = setTimeout(() => {
                    console.log("調用" + num + "次,等待了" + time + "s");
                    this.simplePoller();
                    time *= 1.5
                }, time)
            } else {
                // 執行回調
                return this.callback()
            }
        },
        // 計數 如果超過三次則傳回 true 否則為false
        queryFn: function() {
            num++;
            if (num > 3) return true;
            return false;
        },
        // 回調
        callback: function() {
            console.log("Success callback");
        }
    }
}

simplePoller_2().simplePoller();