竞态

竞态问题:在输入搜索的场景下,我们一般会加 debounce 来避免频繁发请求,即使加了 debounce,先发起的请求也可能后返回,并作为展示结果,此时展示的结果就是错误的。解决方法:发起新请求时,取消旧的请求或者忽略旧的请求

取消旧的请求

const controller = new AbortController()
fetch('...', { signal: controller.signal })
controller.abort()

忽略旧的请求

function onlyResolveLastPromise(func, rejectValue = 'rejected') {
  let outReject
  return function (...rest) {
    if (outReject) {
      outReject(rejectValue)
      outReject = null
    }
    return Promise.race([
      func.apply(this, rest),
      new Promise((resolve, reject) => {
        outReject = reject
      }),
    ])
  }
}

const queryApi = data => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(data)
    }, 1000)
  })
}

const newQueryApi = onlyResolveLastPromise(queryApi)
newQueryApi(1)
  .then(res => console.log(res))
  .catch(err => console.error(err))

newQueryApi(2)
  .then(res => console.log(res))
  .catch(err => console.error(err))

最后更新于