以下asnyc / await,promise和setInterval的混合使用是否存在固有的错误?它可以按预期工作,但是在Edge上的性能却很糟糕。我的测试用例在Chrome中运行大约需要3.5秒,但在Edge中则需要2分钟以上。请注意,这是来自TypeScript类的方法。
public async exportPdf(sourceGraph: IGraph, filters: EntityFilter) {
if (sourceGraph) {
...snip....
for (let verticalPageIndex = 0; verticalPageIndex < pagesHighWithMargins; verticalPageIndex++) {
for (let horizontalPageIndex = 0; horizontalPageIndex < pagesWideWithMargins; horizontalPageIndex++) {
// run with setTimeout so we can process other events between pages and prevent locking up the browser
await new Promise(resolve => setTimeout(resolve, 0)).then(async () => {
...snip...
const svgElement = await exporter.exportSvgAsync(exportComponent) as SVGElement;
....snip - expensive code to convert SVG to PDF page...
});
}
}
return jsPdf.output('datauristring');
} else {
return new Promise((_, reject) => {
reject(new Error('graph argument is null'));
});
}
}
很明显,我是JS和TS的新手,但是我已经有很长的时间了,知道混合使用3种不同的技术来管理异步操作可能是错误的。 :-)
答案 0 :(得分:0)
我正在解决此问题,因为我已经将主要问题-使用Edge浏览器时的性能 隔离到了我用来将SVG转换为PDF的库中使用Promise,setTimeout或async / await,但希望对以下其他发现有更多的了解!
@Bergi的建议很受赞赏,但我可能仍然缺少一些东西。如果我没有在await new Promise(...)
中包含then()
之后的行,则在生成PDF页面内容之前,循环将完成,这将导致下一步-导出完整的PDF内容为字符串并保存到磁盘-失败。我需要此循环来同步完成,因此我将以正确的顺序获取所有PDF内容。我使用new Promise(resolve => setTimeout(resolve, 0))
的唯一原因是在循环过程中略微提高了浏览器的响应能力,该过程的工作原理与原始文章中所示的相当。
我确实从async
的回调中删除了then
,并切换到exportSvg
函数的同步版本,并且运行良好。但是,仅等待对exporter.exportSvgAsync
的调用而没有将其包含在await new Promise(resolve => setTimeout(resolve, 0)).then(...)
中并不能使浏览器在循环内完全响应。