前端竞态问题解决方法

主要是通过 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

posted @ 2022-12-23 19:10  全玉  阅读(97)  评论(0编辑  收藏  举报