我想做的是同时上传多个文件块,然后如果失败则重试每个单独的块 5 次,我已经在 ts Playground 中重新创建了此示例代码,它的工作原理与我的实际代码完全一样,我为简洁起见,省略了使用 XMLHttpRequest 的操作。
这是我的示例代码:
class FileUploader {
onSuccess: ((this: FileUploader) => void) | null;
onFail: ((this: FileUploader) => void) | null;
constructor() {
this.onSuccess = null;
this.onFail = null;
}
run() {
// const num = Math.random();
// if (num > 0.4) {
// this.onGood?.();
// } else {
// this.onBad?.();
// }
// the above code simulated a request failing or succeding.
this.onFail?.();
}
}
async function uploadFile(name: string, retryCount = 0) {
return new Promise<void>(async (resolve, reject) => {
const runner = new FileUploader();
runner.onSuccess = async () => {
await new Promise((res) => setTimeout(res, 500));
resolve();
}
runner.onFail = async () => {
if (retryCount < 5) {
console.log(`Ran ${name}, ${retryCount}`);
const newDelay = Math.pow(2, retryCount) * 100;
await new Promise((res) => setTimeout(res, newDelay));
await uploadFile(name, retryCount + 1);
}
console.log("rejected", name);
reject("error");
}
runner.run();
});
}
async function main() {
try {
await Promise.all([uploadFile("file1"), uploadFile("file2"), uploadFile("file3")])
console.log("success")
}
catch (ex) {
console.log("error")
console.log(ex);
}
}
main();
我想做的是捕获主函数中的错误,我该怎么做?
Promise
构造函数 很棘手,通常不推荐。请参阅使用异步函数调用创建新的 Promise 是不好的做法吗?。主要问题之一是,如果出现问题,很容易无法拒绝承诺。事实上,当你内心深处的承诺被拒绝并且uploadFile()
拒绝时,那就行
await uploadFile(name, retryCount + 1);
将在
Promise
构造函数中抛出错误。这与拒绝承诺不同。你不能拒绝这个承诺,除非你真的打电话给reject()
。避免这种情况的一种方法是使用 catch()
构造函数中的
uploadFile()
函数来 reject
拒绝任何 Promise
”
await uploadFile(name, retryCount + 1).catch(reject);
一旦进行此更改,您将看到所有拒绝都冒出来,然后是拒绝
Promise.all()
:
[LOG]: "rejected", "file1" // 5
[LOG]: "rejected", "file1" // 4
[LOG]: "rejected", "file1" // 3
[LOG]: "rejected", "file1" // 2
[LOG]: "rejected", "file1" // 1
[LOG]: "rejected", "file1" // 0
[LOG]: "error message", "error"
这就是所问问题的答案。
再次,您应该重新考虑在
new Promise()
内部处理 Promise 的任何代码,特别是考虑到错误处理是多么容易出错。但由于这超出了所提出问题的范围,我不会进一步离题。