# 实现一个抓包请求

实现一个并发限制功能

function asyncPool(poolLimit, array, iteratorFn) {
  let i = 0
  const ret = []
  const executing = []
  const enqueue = function () {
    if(i === array.length) return Promise.resolve()
    const item = array[i++]
    const p = Promise.resolve().then(() => iteratorFn(item, array))
    ret.push(p)
    const e = p.then(() => executing.splice(executing.indexOf(e), 1))
    executing.push(e)
    let r = Promise.resolve()
    if(executing.length >= poolLimit) {
      r = Promise.race(executing)
    }
    return r.then(() => enqueue())
  }
  return enqueue().then(() => Promise.all(ret))
}

# 实现一个防抖功能

function debounce(fn, delay, immediate) {
  let timer
  let result
  
  const debounced = function() {
    const context = this
    const args = arguments
    
    if(timer) clearTimeout(timer)
    if(immediate) {
      const callNow = !timer
      timer = setTimeout(function() {
        timer = null
      }, delay)
      if(callNow) result = fn.apply(context, args)
    } else {
      timer = setTimeout(function () {
        fn.apply(context, args)
      }, delay)
    }
  }
  
  debounced.cancel = function() {
    clearTimeout(timer)
    timer = null
  }
  
  return debounced
}

拓展:现在有一个搜索框,已加上防抖按钮,但恰好后面的请求先回来怎么办?

给每个请求添加唯一的 id,对比请求回来的 id 是否是最新 id

或者重新发送请求的时候,取消上一次请求。

# 实现一个图片懒加载

判断页面滚动的时候,图片是否在视口内

# 获取一个异步求和函数