在道具更改时从Promise中取消取消

问题描述 投票:0回答:1

我有一个使用visible bool prop的React组件。 react执行触发长时间运行的Promise的功能,当visible更改时,我需要取消Promise。尝试从外部拒绝Promise不会停止执行。

代码的大致轮廓如下:

<ComponentA visible={visible} />
const ComponentA = ({ visible }) => {
   const [rejectFn, setRejectFn] = useState(() = () => console.log('test');

    useEffect(() => {
        if (visible) {
            ...
        } else {
            setRejectFn();
        }
    }, [visible]);

   const promiseFn = () => (
       new Promise((resolve, reject) => {
            // logic

            const endCallback = (error) => {
                if (error) {
                    reject(error);
                    console.log('error', error);
                } else {
                    resolve(...);
                }
            };

            setRejectFn(() = () => endCallback('exit early'));

            someOtherFn(..., endCallback); // processing file chunk by chunk
       })
   );

   const onDivClick = () => (
      // set some state vars
      promiseFn()
          .then(() => ...)
          .catch(() => ...)
          .finally(() => ...);
   );

   return (
      <div onClick=(onDivClick) />
   );
}

上面的代码将触发rejectFn并记录"exit early",但是Promise将继续执行直到完成。

javascript reactjs promise react-hooks es6-promise
1个回答
0
投票

您去这里:

您无法取消正在进行的承诺请求,但是可以执行类似的操作

  const visibleRef = useRef(visible); // using ref to get latest value inside setInterval

  useEffect(() => {
    visibleRef.current = visible;
    console.log("visible", visible);
  }, [visible]); // <--- Set the value of visible whenever it changes

  const promiseFn = () =>
    new Promise((resolve, reject) => {
      // logic

      // Will check visibleRef.current every second , you can reduce the time as your need
      const interval = setInterval(() => {
        if (!visibleRef.current) { 
          reject("Due to Visible false value");
          clearInterval(interval);
        }
      }, 1000); 

      // just to mock the promise event execution
      setTimeout(() => {
        resolve();
        clearInterval(interval);
      }, 5000);
    });

工作演示

请检查控制台,这将帮助您获得演示的理解

Edit #SO-Promise-cancel-issue

© www.soinside.com 2019 - 2024. All rights reserved.