Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/460.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 是否在卸载时取消承诺中的多个承诺?_Javascript_Reactjs - Fatal编程技术网

Javascript 是否在卸载时取消承诺中的多个承诺?

Javascript 是否在卸载时取消承诺中的多个承诺?,javascript,reactjs,Javascript,Reactjs,嗨,我想取消卸载时的承诺,因为我收到了警告 警告:无法对已卸载的组件执行React状态更新。这是一个no-op,但它表示应用程序中存在内存泄漏。要修复此问题,请取消componentWillUnmount方法中的所有订阅和异步任务 我的代码: const makeCancelable=(promise:promise)=>{ 让hasu=false; const wrappedPromise=新承诺((解决、拒绝)=>{ 我保证,那么( (val)=>(hascanced_u2;reject({

嗨,我想取消卸载时的承诺,因为我收到了警告

警告:无法对已卸载的组件执行React状态更新。这是一个no-op,但它表示应用程序中存在内存泄漏。要修复此问题,请取消
componentWillUnmount
方法中的所有订阅和异步任务

我的代码:

const makeCancelable=(promise:promise)=>{
让hasu=false;
const wrappedPromise=新承诺((解决、拒绝)=>{
我保证,那么(
(val)=>(hascanced_u2;reject({iscancelled:true}):resolve(val)),
(错误)=>(已取消拒绝({isCanceled:true}):拒绝(错误))
);
});
返回{
承诺:wrappedPromise,
取消{
has=true;
},
};
};
useffect(()=>{
const initialize=async()=>{
const getImageFilesystemKey=(remoteUri:string)=>{
const[_,fileName]=remoteUri.split('toolbox-talks/');
返回`${cacheDirectory}${fileName}`;
};
const filesystemmuri=getImageFilesystemKey(uri);
试一试{
//使用缓存的映像(如果存在)
const metadata=wait getInfoAsync(filesystemUri);
if(metadata.exists){
console.log('resolve 1');
setFileUri(filesystemUri);
}否则{
const imageObject=await downloadsync(uri,filesystemUri);
console.log('resolve 2');
setFileUri(imageObject.uri);
}
//否则下载到缓存
}捕捉(错误){
console.log('error 3');
setFileUri(uri);
}
};
const cancelable=makeCancelable(initialize());
可撤销的承诺
.然后(()=>{
console.log('reslved');
})
.catch((e)=>{
console.log('e',e);
});
return()=>{
cancelable.cancel();
};
}, []);

但我仍然在快速按下时收到警告,请帮帮我?

您取消了承诺,但您没有取消axios调用或在
initialize()
中发生的任何逻辑。因此,尽管控制台确实不会打印
resolved
,但无论如何都会调用
setFileUri
,这会导致您的问题

解决方案可能如下所示(未经测试):

const makeCancelable=(promise:promise)=>{
让hasu=false;
const wrappedPromise=新承诺((解决、拒绝)=>{
我保证,那么(
val=>(hasCancelled_2;reject({isCanceled:true}):resolve(val)),
error=>(hasCancelled_10;reject({isCanceled:true}):reject(error))
);
});
返回{
承诺:wrappedPromise,
取消{
has=true;
}
};
};
const initialize=async()=>{
const getImageFilesystemKey=(remoteUri:string)=>{
const[\ux,fileName]=remoteUri.split(“工具箱对话/”);
返回`${cacheDirectory}${fileName}`;
};
const filesystemmuri=getImageFilesystemKey(uri);
试一试{
//使用缓存的映像(如果存在)
const metadata=wait getInfoAsync(filesystemUri);
if(metadata.exists){
控制台日志(“解析1”);
返回文件系统;
}否则{
const imageObject=await downloadsync(uri,filesystemUri);
控制台日志(“解析2”);
返回imageObject.uri;
}
//否则下载到缓存
}捕捉(错误){
控制台错误(“错误3”,错误);
返回uri;
}
};
useffect(()=>{
const cancelable=makeCancelable(initialize());
可以取消,答应吧(
fileURI=>{
控制台日志(“已解决”);
setFileUri(fileURI);
},
() => {
//你的逻辑是,只有在承诺被取消的情况下才有可能到达这里
控制台日志(“取消”);
}
);
return()=>{
cancelable.cancel();
};
}, []);
这确保了只有在承诺没有取消的情况下(我没有检查
makeCancelable
)才会调用
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();
  };
}, []);