前端竞态问题解决方法
主要是通过 AbortController 来终止前一个请求。
例如:
useEffect(() => { // 创建 controller const controller = new AbortController(); // 将 controller 作为signal传递给 fetch fetch(url, { signal: controller.signal }) .then((r) => r.json()) .then((r) => { setData(r); }) .catch((error) => { // 由于 AbortController 导致的错误 if (error.name === 'AbortError') { // ... } else { // ... } }); return () => { // 中止请求 controller.abort(); }; }, [url]);
或者终止任意的promise
function wait(time: number, signal?: AbortSignal) { return new Promise<void>((resolve, reject) => { const timeoutId = setTimeout(() => { resolve(); }, time); signal?.addEventListener('abort', () => { clearTimeout(timeoutId); reject(); }); }); } const abortController = new AbortController(); setTimeout(() => { abortController.abort(); }, 1000); wait(5000, abortController.signal) .then(() => { console.log('5 seconds passed'); }) .catch(() => { console.log('Waiting was interrupted'); });
出处: https://mp.weixin.qq.com/s/Ja1Fmehn3pIiUPDoAnoL1Q
https://mp.weixin.qq.com/s/KHxkXW7vUKZKeG9EBe5KcQ