竞态问题:在输入搜索的场景下,我们一般会加 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))