瀏覽器端異步超時檢測

在寫JavaScript代碼的時候,異步回調是一個很是常見的特徵。完善的回調會有和超時相關的設置,例如Ajax的timeout選項。那若是SDK提供的異步調用函數中沒有提供超時設置,在出現異常的時候就只能乾等了嗎?這固然是不能忍的。
app

咱們先構造一個沒有提供超時設置的回調函數:異步

function myTimeout(options) {
  options = options || {};
  setTimeout(function () {
    options.callback("called!");
  }, 5000);
}

上面的代碼很簡單,5秒後回調送進去的回調函數。若是咱們要爲這個異步回調提供超時設置,例如3秒鐘超時,那麼該怎麼弄呢?函數

(function () {

var oldMyTimeout = myTimeout;
myTimeout = function (options) {
  var timeoutFlag = false;
  var timeoutHandle = -1;
  var timeout = options.timeout;
  var callback = options.callback;
  var hookCallback = function () {
    if(timeoutFlag == true) return;        // 檢測到超時,再也不執行後面的實際回調函數
    clearTimeout(timeoutHandle);           // 清空超時控制器
    return callback.apply(this, Array.prototype.slice.call(arguments));  //調用原始的回調函數
  }
  options.callback = hookCallback;
  
  if(timeout > 0) {  // 超時設置小於0時,不進行超時檢測
    timeoutHandle = setTimeout(function() {
      timeoutFlag = true;
      callback("已經超時(" + timeout + "ms)");
    }, timeout);
  }
  oldMyTimeout(options);
}

})();

能夠用下面代碼進行測試:測試

// called!
myTimeout({
  callback: function (data) {console.log(data);},
  timeout: 6000
});

// 已經超時(4000ms)
myTimeout({
  callback: function (data) {console.log(data);},
  timeout: 4000
});
相關文章
相關標籤/搜索