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