1.2.7 • Published 1 month ago

bs-common-util v1.2.7

Weekly downloads
-
License
MIT
Repository
-
Last release
1 month ago

'use strict'

/**
 * 工具类
 * util.js
 */
const REG_PHONE = /^\d{11}$/ // 手机号
const REG_VCODE = /^\d{6}$/ // 验证码
const REG_CARDNUMBER = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/ // 身份证号
const REG_CHINESE_NAME = /^[\u4E00-\u9FA5]{2,4}$/ // 中文姓名
const REG_PASSWORD = /^[0-9A-Za-z]{6,20}$/

// 正则手机号码
function testPhone(v) {
  return REG_PHONE.test(v)
}

exports.testPhone = testPhone

// 正则短信验证码
function testVcode(v) {
  return REG_VCODE.test(v)
}

exports.testVcode = testVcode

// 正则身份证号码
function testCardNumber(v) {
  return REG_CARDNUMBER.test(v)
}

exports.testCardNumber = testCardNumber

// 正则登录密码
function testPassword(v) {
  return REG_PASSWORD.test(v)
}

exports.testPassword = testPassword

// 正则是否为空
function testEmpty(v) {
  return String(v).trim() === '' || v === null
}

exports.testEmpty = testEmpty

// 正则姓名
function testChineseName(v) {
  return REG_CHINESE_NAME.test(v)
}

exports.testChineseName = testChineseName

/**
 * 安全处理接口返回的message数据
 *
 * 注:当返回的message为空,可以用自定义 字符串 替换
 *
 * @param resp 响应数据
 * @param replaceMsg 如果返回的 message 为空,则用改值替换
 */
function safeHandleResponseMessage(resp, replaceMsg) {
  let replaceMsgStr = replaceMsg ? replaceMsg : '服务异常'

  if (!resp) {
    return replaceMsgStr
  }

  if (!resp.message && !resp.msg) {
    return replaceMsgStr
  }

  if (resp.message) {
    if (resp.message.length == 0) {
      return replaceMsgStr
    } else {
      return resp.message
    }
  }

  if (resp.msg) {
    if (resp.msg.length == 0) {
      return replaceMsgStr
    } else {
      return resp.msg
    }
  }

  return replaceMsgStr
}

exports.safeHandleResponseMessage = safeHandleResponseMessage

/**
 * 根据身份证号码获取出生日期
 * @param {String} idCard
 */
function getBirthdayFromIdCard(idCard) {
  let birthday = ''
  if (idCard != null && idCard !== '') {
    if (idCard.length === 15) {
      birthday = '19' + idCard.substr(6, 6)
    } else if (idCard.length === 18) {
      birthday = idCard.substr(6, 8)
    }

    birthday = birthday.replace(/(.{4})(.{2})/, '$1-$2-')
  }
  return birthday
}

exports.getBirthdayFromIdCard = getBirthdayFromIdCard

/**
 * 根据身份证号码获取性别
 * @param {String} idCard
 */
function getSexFromIdCard(idCard) {
  const len = (idCard + '').length
  if (len === 15) {
    return idCard.substr(14, 1) % 2 === 1 ? '1' : '2'
  } else if (len === 18) {
    return idCard.substr(16, 1) % 2 === 1 ? '1' : '2'
  }
  return '1'
}

exports.getSexFromIdCard = getSexFromIdCard

/**
 * 根据身份证号码获取年龄
 * @param {String} idCard
 */
function getAgeFromIdCard(idCard) {
  const len = (idCard + '').length
  let strBirthday = ''
  if (len == 18) {
    //处理18位的身份证号码从号码中得到生日和性别代码
    strBirthday =
      idCard.substr(6, 4) +
      '/' +
      idCard.substr(10, 2) +
      '/' +
      idCard.substr(12, 2)
  }
  if (len == 15) {
    let birthdayValue = ''
    birthdayValue = idCard.charAt(6) + idCard.charAt(7)
    if (parseInt(birthdayValue) < 10) {
      strBirthday =
        '20' +
        idCard.substr(6, 2) +
        '/' +
        idCard.substr(8, 2) +
        '/' +
        idCard.substr(10, 2)
    } else {
      strBirthday =
        '19' +
        idCard.substr(6, 2) +
        '/' +
        idCard.substr(8, 2) +
        '/' +
        idCard.substr(10, 2)
    }
  }
  // 时间字符串里,必须是“/”
  const birthDate = new Date(strBirthday)
  const nowDateTime = new Date()
  let age = nowDateTime.getFullYear() - birthDate.getFullYear()
  //再考虑月、天的因素;.getMonth()获取的是从0开始的,这里进行比较,不需要加1
  if (
    nowDateTime.getMonth() < birthDate.getMonth() ||
    (nowDateTime.getMonth() == birthDate.getMonth() &&
      nowDateTime.getDate() < birthDate.getDate())
  ) {
    age--
  }
  return age
}

exports.getAgeFromIdCard = getAgeFromIdCard

// Parse the time to string
const parseTime = (time, cFormat) => {
  if (time === undefined || !time) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if (typeof time === 'string') {
      if (/^[0-9]+$/.test(time)) {
        // support "1548221490638"
        time = parseInt(time)
      } else {
        // support safari
        // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
        time = time.replace(new RegExp(/-/gm), '/')
      }
    }
    if (typeof time === 'number' && time.toString().length === 10) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay(),
  }
  const timeStr = format.replace(/{([ymdhisa])+}/g, (result, key) => {
    const value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value]
    }
    return value.toString().padStart(2, '0')
  })
  return timeStr
}

exports.parseTime = parseTime

/**
 * 根据日期获取年龄
 * @param {String} date
 */
function getAgeFromDate(str) {
  const r = str.match(/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/)
  if (r == null) return false
  const d = new Date(r[1], r[3] - 1, r[4])
  if (
    d.getFullYear() == r[1] &&
    d.getMonth() + 1 == r[3] &&
    d.getDate() == r[4]
  ) {
    const Y = new Date().getFullYear()
    return Y - r[1]
  }
  return '输入的日期格式错误!'
}

exports.getAgeFromDate = getAgeFromDate

/**
 * 格式化日期
 * @param {Date} date
 * @param {String} fmt 'yyyy-MM-dd hh:mm:ss'
 */
function formatDate(date, fmt) {
  let padLeftZero = (str) => ('00' + str).substr(str.length)
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(
      RegExp.$1,
      (date.getFullYear() + '').substr(4 - RegExp.$1.length)
    )
  }
  let o = {
    'M+': date.getMonth() + 1,
    'd+': date.getDate(),
    'h+': date.getHours(),
    'm+': date.getMinutes(),
    's+': date.getSeconds(),
  }
  for (let k in o) {
    if (new RegExp(`(${k})`).test(fmt)) {
      let str = o[k] + ''
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length === 1 ? str : padLeftZero(str)
      )
    }
  }
  return fmt
}

exports.formatDate = formatDate

// 计算剩余时间
function leftTime(time1, time2) {
  let syhm = time1 - time2
  let day = 0
  let hour = 0
  let minite = 0
  let second = 0
  if (syhm > 0) {
    day = Math.floor(syhm / 1000 / 60 / 60 / 24)
    hour = Math.floor((syhm / 1000 / 60 / 60) % 24)
    minite = Math.floor((syhm / 1000 / 60) % 60)
    second = Math.floor((syhm / 1000) % 60)
  }
  return {
    day,
    hour,
    minite,
    second,
  }
}

exports.leftTime = leftTime

// 获取当前日期
function getCurrentDate() {
  let weeks = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
  let d = new Date()
  let d2 = formatDate(d, 'yyyy年MM月dd日 ')
  return d2 + weeks[d.getDay()]
}

exports.getCurrentDate = getCurrentDate

/**
 * 获取周
 */
function getCurrentWeek(str) {
  let weeks = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
  let d = new Date(str.replace(/-/g, '/'))
  return weeks[d.getDay()]
}

exports.getCurrentWeek = getCurrentWeek

/**
 * 获取时间段
 */
function getCurrentPeriod(str) {
  let d = new Date(str.replace(/-/g, '/'))
  const hour = d.getHours()
  let hourStr = ''
  if (hour <= 12) {
    hourStr = '上午'
  } else if (hour > 12 && hour < 18) {
    hourStr = '下午'
  } else {
    hourStr = '晚上'
  }

  return hourStr
}

exports.getCurrentPeriod = getCurrentPeriod

/**
 * 获取当前日期 yyyy-MM-dd
 */
function getCurrentDateNormal() {
  let d = new Date()
  let d2 = formatDate(d, 'yyyy-MM-dd')
  return d2
}

exports.getCurrentDateNormal = getCurrentDateNormal

/**
 * 获取当前日期yyyy-MM-dd
 */
function getNowDate() {
  const date = new Date()
  let month = date.getMonth() + 1
  let strDate = date.getDate()

  if (month <= 9) {
    month = '0' + month
  }

  if (strDate <= 9) {
    strDate = '0' + strDate
  }

  return date.getFullYear() + '-' + month + '-' + strDate
}

exports.getNowDate = getNowDate

/**
 * 获取昨天日期 yyyy-MM-dd
 */
function getYesterdayDateNormal() {
  let d = new Date().setDate(new Date().getDate() - 1)
  let d2 = formatDate(new Date(d), 'yyyy-MM-dd')
  return d2
}

exports.getYesterdayDateNormal = getYesterdayDateNormal

/**
 * 获取当前日期 yyyy-MM-dd hh:mm:ss
 */
function getCurrentDateDetailNormal() {
  let d = new Date()
  let d2 = formatDate(d, 'yyyy-MM-dd hh:mm:ss')
  return d2
}

exports.getCurrentDateDetailNormal = getCurrentDateDetailNormal

/**
 * 获取当前年份 yyyy
 */
function getCurrentYearNormal() {
  let date = new Date()
  return date.getFullYear()
}

exports.getCurrentYearNormal = getCurrentYearNormal

function getWeekName(week) {
  let weeks = ['', '周日', '周一', '周二', '周三', '周四', '周五', '周六']
  return weeks[week]
}

exports.getWeekName = getWeekName

/**
 * 格式化日期
 * @param 时间毫秒数
 * @param {String} fmt '天、时
 */
function formatDuringHours(mss) {
  const days = parseInt(mss / (1000 * 60 * 60 * 24))
  const hours = parseInt((mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
  const minutes = parseInt((mss % (1000 * 60 * 60)) / (1000 * 60))
  const minutesTrue = minutes.toString().length < 2 ? '0' + minutes : minutes
  const seconds = parseInt((mss % (1000 * 60)) / 1000)
  const secondsTrue = seconds.toString().length < 2 ? '0' + seconds : seconds
  const hoursTrue = hours
    ? hours.toString().length < 2
      ? '0' + hours
      : hours
    : ''
  return hoursTrue
    ? days * 24 + hours + '小时'
    : minutesTrue
    ? minutesTrue + '分'
    : secondsTrue + '秒'
}

exports.formatDuringHours = formatDuringHours

/**
 * 格式化日期
 * @param 时间毫秒数
 * @param {String} fmt '天、时、分、秒'
 */
function formatDuring(mss) {
  const days = parseInt(mss / (1000 * 60 * 60 * 24))
  const daysTrue = days ? (days.toString().length < 2 ? '0' + days : days) : ''
  const hours = parseInt((mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
  const hoursTrue = hours
    ? hours.toString().length < 2
      ? '0' + hours
      : hours
    : ''
  const minutes = parseInt((mss % (1000 * 60 * 60)) / (1000 * 60))
  const minutesTrue = minutes.toString().length < 2 ? '0' + minutes : minutes
  const seconds = parseInt((mss % (1000 * 60)) / 1000)
  const secondsTrue = seconds.toString().length < 2 ? '0' + seconds : seconds
  return (
    (hoursTrue ? days * 24 + hours + '时' : '') +
    (minutesTrue ? minutesTrue + '分' : '') +
    secondsTrue +
    '秒'
  )
}

exports.formatDuring = formatDuring

/**
 * 格式化日期
 * @param 时间毫秒数
 * @param {String} fmt '天、时、分、秒'
 */
function formatDuringNormal(mss) {
  const days = parseInt(mss / (1000 * 60 * 60 * 24))
  const daysTrue = days ? (days.toString().length < 2 ? '0' + days : days) : ''
  const hours = parseInt((mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
  const hoursTrue = hours.toString().length < 2 ? '0' + hours : hours
  const minutes = parseInt((mss % (1000 * 60 * 60)) / (1000 * 60))
  const minutesTrue = minutes.toString().length < 2 ? '0' + minutes : minutes
  const seconds = parseInt((mss % (1000 * 60)) / 1000)
  const secondsTrue = seconds.toString().length < 2 ? '0' + seconds : seconds
  return (
    (daysTrue ? daysTrue + '天' : '') +
    hoursTrue +
    ':' +
    (minutesTrue ? minutesTrue + ':' : '') +
    secondsTrue
  )
}

exports.formatDuringNormal = formatDuringNormal

// Date型数据转换成yyyy-MM-dd
function dateToNormal(date) {
  if (date && typeof date === 'object') {
    const dateTrue = new Date(date)
    return formatDate(dateTrue, 'yyyy-MM-dd')
  }
  return date
}

exports.dateToNormal = dateToNormal

// 获取日期
function objectDate(date) {
  if (date && typeof date === 'string') {
    date = new Date(date)
    let o = {
      Y: date.getFullYear(),
      M: date.getMonth() + 1,
      D: date.getDate(),
    }
    return o
  }
  return date
}

exports.objectDate = objectDate

// 深拷贝
function deepCopy(obj) {
  return JSON.parse(JSON.stringify(obj))
}

exports.deepCopy = deepCopy

/**
 * 获取url参数
 */
function GetRequest(to) {
  let url = to || ''
  let theRequest = {}
  if (url.indexOf('?') !== -1) {
    let str = url.split('?')[2]
    let strs = str.split('&')
    for (let i = 0; i < strs.length; i++) {
      theRequest[strs[i].split('=')[0]] = unescape(strs[i].split('=')[1])
    }
  }
  return theRequest
}

exports.GetRequest = GetRequest

/**
 * 获取url参数,注意该URL=scheme://host/path?params
 */
function GetRequestOne(to) {
  let url = to || ''
  let theRequest = {}
  if (url.indexOf('?') !== -1) {
    let str = url.split('?')[1]
    let strs = str.split('&')
    for (let i = 0; i < strs.length; i++) {
      theRequest[strs[i].split('=')[0]] = unescape(strs[i].split('=')[1])
    }
  }
  return theRequest
}

exports.GetRequestOne = GetRequestOne

// 获取开始和结束时间
function getWeekStartAndEnd(d) {
  let now = new Date()
  let nowTime = now.getTime()
  let day = now.getDay()
  let oneday = 60 * 60 * 24 * 1000
  let sunday = nowTime - (-1 * d + day) * oneday
  let satday = nowTime + (d + 6 - day) * oneday
  return {
    start: formatDate(new Date(sunday), 'yyyy-MM-dd'),
    end: formatDate(new Date(satday), 'yyyy-MM-dd'),
  }
}

exports.getWeekStartAndEnd = getWeekStartAndEnd

// 日期之差
function DateDiff(sDate1, sDate2) {
  let aDate, oDate1, oDate2, iDays
  aDate = sDate1.split('-')
  oDate1 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0])
  aDate = sDate2.split('-')
  oDate2 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0])
  iDays = Number((Number(oDate1) - Number(oDate2)) / 1000 / 60 / 60 / 24) // 把相差的毫秒数转换为天数
  return iDays
}

exports.DateDiff = DateDiff

// 根据年份获取年龄
function getAgeFromBirthday(birthday) {
  if (!birthday) {
    return 0
  }
  let bornYear = birthday.substring(0, 4)
  let curYear = new Date().getFullYear()
  return curYear - Number(bornYear)
}

exports.getAgeFromBirthday = getAgeFromBirthday

function isWechatBrowser() {
  let ua = navigator.userAgent.toLowerCase()
  return ua.indexOf('micromessenger') > -1
}

exports.isWechatBrowser = isWechatBrowser

// const browser = {
//   versions: (function () {
//     const u = navigator.userAgent
//     return {
//       trident: u.indexOf('Trident') > -1, // IE内核
//       presto: u.indexOf('Presto') > -1, // opera内核
//       webKit: u.indexOf('AppleWebKit') > -1, // 苹果、谷歌内核
//       gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') === -1, // 火狐内核
//       mobile: !!u.match(/AppleWebKit.*Mobile.*/), // 是否为移动终端
//       ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), // ios终端
//       android: u.indexOf('Android') > -1 || u.indexOf('Adr') > -1, // android终端
//       iPhone: u.indexOf('iPhone') > -1, // 是否为iPhone或者QQHD浏览器
//       iPad: u.indexOf('iPad') > -1, // 是否iPad
//       webApp: u.indexOf('Safari') === -1, // 是否web应该程序,没有头部与底部
//       weixin: u.indexOf('MicroMessenger') > -1, // 是否微信 (2015-01-22新增)
//       qq: u.match(/\sQQ/i) === ' qq', // 是否QQ
//     }
//   })(),
//   language: (navigator.browserLanguage || navigator.language).toLowerCase(),
// }

// exports.testPhone = testPhone;

// 获取年龄
const formatDateGetAge = (now) => {
  let Y = now.getFullYear()
  let year = new Date().getFullYear()
  return year - Y
}

exports.formatDateGetAge = formatDateGetAge

// 获取时间
function getTime(val) {
  if (!val) {
    return ''
  }
  return val.slice(11, 16)
}

exports.getTime = getTime

// 获取支付方式
function filterPayMode(val) {
  return ['', '支付宝', '微信'][val]
}

exports.filterPayMode = filterPayMode

// 性别编号
function sexDoc(str) {
  if (!str) {
    return ''
  }
  let cardTypesDic = {
    男: '1',
    女: '2',
  }
  return cardTypesDic[str]
}

exports.sexDoc = sexDoc

// 国籍编号
function nationaliyDoc(str) {
  if (!str) {
    return ''
  }
  let cardTypesDic = {
    中国: '01',
    中国香港澳门: '02',
    中国台湾: '03',
    海外: '04',
  }
  return cardTypesDic[str]
}

exports.nationaliyDoc = nationaliyDoc

// 身份证编号
function idCardTypeDoc(str) {
  if (!str) {
    return ''
  }
  let cardTypesDic = {
    居民身份证: '01',
    居民户口簿: '02',
    护照: '03',
    军官证: '04',
    驾驶证: '05',
    港澳居民来往内地通行证: '06',
    台湾居民来往内地通行证: '07',
    出生证明: '08',
    港澳居民身份证: '09',
    港澳居民居住证: '10',
    其他法定有效证件: '99',
  }
  return cardTypesDic[str]
}

exports.idCardTypeDoc = idCardTypeDoc

/**
 * 根据传过来的字符串 数值
 * 来展示当前内容
 * @param {String} val
 * @param {Number} num
 */
function accordingNumToShow(val, num) {
  if (val && val.length > num) {
    return val.substr(0, num) + '...'
  } else {
    return val
  }
}

exports.accordingNumToShow = accordingNumToShow

/**
 * 根据传过来的两个object
 * 判断键值对是否相等
 */
function isObjectValueEqual(a, b) {
  const aProps = Object.getOwnPropertyNames(a)
  const bProps = Object.getOwnPropertyNames(b)
  if (aProps.length != bProps.length) {
    return false
  }
  for (let i = 0; i < aProps.length; i += 1) {
    const propName = aProps[i]

    const propA = a[propName]
    const propB = b[propName]
    if (typeof propA === 'object') {
      if (isObjectValueEqual(propA, propB)) {
        return true
      } else {
        return false
      }
    } else if (propA !== propB) {
      return false
    } else {
      return true
    }
  }
  return true
}

exports.isObjectValueEqual = isObjectValueEqual

/**
 * 判断当前字符串是否存在
 */
function isStringExist(str) {
  if (!str) {
    return ''
  }
  return str
}

exports.isStringExist = isStringExist

// 当前时间
const getTimer = (FAT = 'YMD', FAG = '-', CUR) => {
  let date = ''
  if (CUR) {
    date = new Date(CUR)
  } else {
    date = new Date()
  }
  let year = date.getFullYear()
  let month =
    date.getMonth() < 9
      ? '0' + (Number(date.getMonth()) + 1)
      : date.getMonth() + 1
  let day = date.getDate() > 9 ? date.getDate() : '0' + date.getDate()
  let hours = date.getHours() > 9 ? date.getHours() : '0' + date.getHours()
  let minutes =
    date.getMinutes() > 9 ? date.getMinutes() : '0' + date.getMinutes()
  let seconds =
    date.getSeconds() > 9 ? date.getSeconds() : '0' + date.getSeconds()
  switch (FAT) {
    case 'YMD':
      return year + FAG + month + FAG + day
    case 'HM':
      return hours + ':' + minutes
    case 'HMS':
      return hours + ':' + minutes + ':' + seconds
    case 'YMDHMS':
      return (
        year +
        FAG +
        month +
        FAG +
        day +
        ' ' +
        hours +
        ':' +
        minutes +
        ':' +
        seconds
      )
    default:
      return '指令无法识别!'
  }
}

exports.getTimer = getTimer

// 判断是否是json字符串
function isJSON(str) {
  if (typeof str == 'string') {
    try {
      const obj = JSON.parse(str)
      if (typeof obj == 'object' && obj) {
        return true
      } else {
        return false
      }
    } catch (e) {
      console.log('error:' + str + '!!!' + e)
      return false
    }
  }
  console.log('It is not a string!')
  return true
}

exports.isJSON = isJSON

// 判断当前字符串是存在
function isStrEmpty(str) {
  if (!str) {
    return true
  }
  if (String(str).trim() === '' || str === null) {
    return true
  }
  return false
}

exports.isStrEmpty = isStrEmpty

// 判断当前图片url模式
function getInitImgUrl(url) {
  if (url.includes('?')) {
    return url + '&length=100&width=100'
  } else {
    return url + '?length=100&width=100'
  }
}

exports.getInitImgUrl = getInitImgUrl

/**
 * 金额,只允许2位小数
 */
function amount(value) {
  //金额,只允许保留两位小数
  return /^[1-9]\d*(,\d{3})*(\.\d{1,2})?$|^0\.\d{1,2}$/.test(value)
}

exports.amount = amount

let timer, flag
/**
 * 节流原理:在一定时间内,只能触发一次
 *
 * @param {Function} func 要执行的回调函数
 * @param {Number} wait 延时的时间
 * @param {Boolean} immediate 是否立即执行
 * @return null
 */
function throttle(func, wait = 500, immediate = true) {
  if (immediate) {
    if (!flag) {
      flag = true
      // 如果是立即执行,则在wait毫秒内开始时执行
      typeof func === 'function' && func()
      timer = setTimeout(() => {
        flag = false
      }, wait)
    }
  } else {
    if (!flag) {
      flag = true
      // 如果是非立即执行,则在wait毫秒内的结束处执行
      timer = setTimeout(() => {
        flag = false
        typeof func === 'function' && func()
      }, wait)
    }
  }
}

exports.throttle = throttle

let timeout = null

/**
 * 防抖原理:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数
 *
 * @param {Function} func 要执行的回调函数
 * @param {Number} wait 延时的时间
 * @param {Boolean} immediate 是否立即执行
 * @return null
 */
function debounce(func, wait = 500, immediate = false) {
  // 清除定时器
  if (timeout !== null) clearTimeout(timeout)
  // 立即执行,此类情况一般用不到
  if (immediate) {
    var callNow = !timeout
    timeout = setTimeout(function () {
      timeout = null
    }, wait)
    if (callNow) typeof func === 'function' && func()
  } else {
    // 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法
    timeout = setTimeout(function () {
      typeof func === 'function' && func()
    }, wait)
  }
}

exports.debounce = debounce