function debounce(func, wait, immediate) {

  var timeout, result;

  var debounced = function () {
    // 保存this,setTimeout中的this会丢失
    var context = this;
    // 保存参数,比如event
    var args = arguments;

    timeout && clearTimeout(timeout);

    if (immediate) {
        // 如果已经执行过,不再执行
        var callNow = !timeout;
        timeout = setTimeout(function(){
            timeout = null;
        }, wait)
        if (callNow) result = func.apply(context, args)
    }
    else {
      timeout = setTimeout(function(){
        func.apply(context, args)
      }, wait);
    }
    return result;
  };

  debounced.cancel = function() {
    clearTimeout(timeout);
    timeout = null;
  };

  return debounced;
}