我有一个方法,用于压缩和保存JSON数组的响应,并将它们分割成单独的文件。
zip: JSZip = new JSZip();
folder: JSZip = new JSZip();
this.apicall.api1()
.subscribe(
response => {
for (let r of response) {
this.folder = this.zip.folder("result/api1");
this.folder.file(`${r.actorname}.json`, JSON.stringify(r));
}
this.zip.generateAsync({type:"blob"}).then(function(content) {
saveAs(content, "result.zip");
});
});但是我有多个api调用(由于执行时的选择,所有调用都可能/不一定被调用)
this.apicall.api2(), this.apicall.api3(), this.apicall.api4()等等
我想把每个结果放在一个单独的文件夹中,如上面的"result/api2"、"result/api3"等。一旦全部完成,我们就把它放到result.zip中
我们如何将generateAsync从api1()中移出,然后使用不同的文件夹结构将其他方法的结果提供给它并生成最终的zip?
发布于 2022-07-12 00:12:27
使用Promise.all。
它需要一个承诺数组,然后返回一个承诺,当所有异步代码(API调用)成功完成后,这个承诺就会得到解决。然后,您可以对所有返回的响应进行最后的回调。
如下所示:
zip: JSZip = new JSZip();
async zipProcess(): Promise<void> {
try {
const callsAndNames = [
{ name: 'api1', call: this.apicall.api1 },
{ name: 'api2', call: this.apicall.api2 },
{ name: 'api3', call: this.apicall.api3 },
{ name: 'api4', call: this.apicall.api4 }
// ...
];
const responsesAndNames = await Promise.all(
callsAndNames.map(async ({ name, call }) => ({
name,
response: await firstValueFrom(call())
}))
);
responsesAndNames.forEach(({ name, response }) => {
const folder = this.zip.folder(`result/${name}`);
for (let r of response) {
folder.file(`${r.actorname}.json`, JSON.stringify(r));
}
});
this.zip.generateAsync({ type: 'blob' }).then(function (content) {
saveAs(content, 'result.zip');
});
} catch (error) {
/* handle error */
console.error(error);
}
}
await this.zipProcess();代码可能不是您想要的,但是我认为它应该给您一个如何使用Promise.all的概述。
考虑到每个API调用都有一个名称,所以在zip文件夹中添加响应时,名称仍然可用。
我是单行的粉丝,他们让代码更短。所以我用了很多,希望这不是你的问题。特别是当我在函数参数中将它们与对象破坏组合时。
我还用“尝试和捕捉”来包装整件事情,因为我们应该始终处理可能的错误。
我根据我的感觉调整了文件夹逻辑,如果我错了,在你的实现中改进它。
firstValueFrom是rxjs包中的一个函数,它将可观察性转换为承诺。lastValueFrom。我使用firstValueFrom是因为我在代码中注意到了.subscribe,并暗示.apiN方法返回可观察的而不是承诺。因此,我们需要将可观察性转换为承诺使用Promise.all语法。
如果这是错误的,或者如果您希望这个过程不断重复,这就是可观察的不断从这些调用中发出值,而不是承诺只解析一次并停止;那么也许您不应该使用Promise.all,而是使用rxjs操作符(如combineLatest或merge )在进入文件夹压缩逻辑之前获得API结果值。
但是这是一个API调用,所以您很可能希望它只运行一次,因此Promise.all就足够了。
https://stackoverflow.com/questions/72945322
复制相似问题