亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在卸載時取消承諾內的多個承諾?

在卸載時取消承諾內的多個承諾?

三國紛爭 2023-07-20 16:31:16
您好,自從收到警告以來,我想取消卸載承諾,警告:無法對已卸載的組件執行 React 狀態更新。這是一個空操作,但它表明應用程序中存在內存泄漏。要修復此問題,請取消該方法中的所有訂閱和異步任務componentWillUnmount。我的代碼:const makeCancelable = (promise: Promise<void>) => {  let hasCanceled_ = false;  const wrappedPromise = new Promise((resolve, reject) => {    promise.then(      (val) => (hasCanceled_ ? reject({ isCanceled: true }) : resolve(val)),      (error) => (hasCanceled_ ? reject({ isCanceled: true }) : reject(error))    );  });  return {    promise: wrappedPromise,    cancel() {      hasCanceled_ = true;    },  };};useEffect(() => {  const initialize = async () => {    const getImageFilesystemKey = (remoteUri: string) => {      const [_, fileName] = remoteUri.split('toolbox-talks/');      return `${cacheDirectory}${fileName}`;    };    const filesystemUri = getImageFilesystemKey(uri);    try {      // Use the cached image if it exists      const metadata = await getInfoAsync(filesystemUri);      if (metadata.exists) {        console.log('resolve 1');        setFileUri(filesystemUri);      } else {        const imageObject = await downloadAsync(uri, filesystemUri);        console.log('resolve 2');        setFileUri(imageObject.uri);      }      // otherwise download to cache    } catch (err) {      console.log('error 3');      setFileUri(uri);    }  };  const cancelable = makeCancelable(initialize());  cancelable.promise    .then(() => {      console.log('reslved');    })    .catch((e) => {      console.log('e ', e);    });  return () => {    cancelable.cancel();  };}, []);但我仍然在快速按下時收到警告,請幫助我嗎?
查看完整描述

1 回答

?
不負相思意

TA貢獻1777條經驗 獲得超10個贊

您正在取消承諾,但您并沒有取消 axios 調用或在它之后發生的任何邏輯initialize()。因此,雖然控制臺確實不會 print resolved,但setFileUri無論如何都會被調用,這會導致您的問題。

解決方案可能如下所示(未經測試):

const makeCancelable = (promise: Promise<void>) => {

  let hasCanceled_ = false;


  const wrappedPromise = new Promise((resolve, reject) => {

    promise.then(

      val => (hasCanceled_ ? reject({ isCanceled: true }) : resolve(val)),

      error => (hasCanceled_ ? reject({ isCanceled: true }) : reject(error))

    );

  });


  return {

    promise: wrappedPromise,

    cancel() {

      hasCanceled_ = true;

    }

  };

};


const initialize = async () => {

  const getImageFilesystemKey = (remoteUri: string) => {

    const [_, fileName] = remoteUri.split("toolbox-talks/");

    return `${cacheDirectory}${fileName}`;

  };


  const filesystemUri = getImageFilesystemKey(uri);


  try {

    // Use the cached image if it exists

    const metadata = await getInfoAsync(filesystemUri);


    if (metadata.exists) {

      console.log("resolve 1");

      return filesystemUri;

    } else {

      const imageObject = await downloadAsync(uri, filesystemUri);

      console.log("resolve 2");

      return imageObject.uri;

    }

    // otherwise download to cache

  } catch (err) {

    console.error("error 3", err);

    return uri;

  }

};


useEffect(() => {

  const cancelable = makeCancelable(initialize());


  cancelable.promise.then(

    fileURI => {

      console.log("resolved");

      setFileUri(fileURI);

    },

    () => {

      // Your logic is such that it's only possible to get here if the promise is cancelled

      console.log("cancelled");

    }

  );


  return () => {

    cancelable.cancel();

  };

}, []);

這確保了只有setFileUri在promise沒有取消的情況下你才會調用(我沒有檢查邏輯makeCancelable)。


查看完整回答
反對 回復 2023-07-20
  • 1 回答
  • 0 關注
  • 155 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號