javascript - 取消卸载承诺中的多个承诺?
问题描述
嗨,由于收到警告,我想取消卸载承诺,
警告:无法对未安装的组件执行 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();
};
}, []);
但我仍然在快速按下时收到警告,请帮帮我?
解决方案
您正在取消承诺,但您并没有取消 axios 调用或在它内部发生的任何逻辑initialize()
。因此,虽然控制台不会打印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
在未取消承诺时才调用(我没有检查 的逻辑makeCancelable
)。
推荐阅读
- ios - 原生脚本IOS部署
- nativescript-angular - 错误:在升级到 NativeScript 6.0 时,预期的“样式”是字符串数组
- r - 使用来自另一个数据帧的起点和终点对数据帧进行子集?
- exec - 如何将打印的 C 控制台导入节点红色
- sass - scss mixins 不工作错误标识符预期scss
- docker - 如何使用 nftables 从系统上的 Docker 容器发布端口?
- linux - Linux tail 命令包含比预期更多的行
- php - 如何根据访问方式显示信息
- swift - Swift 5,如何在从 Firebase 获取所有添加的子项后执行代码
- asp.net-core - IdentityServer 4 - 自定义 IExtensionGrantValidator 总是返回 invalid_grant