以下混合使用asnyc/await、诺言和setInterval有什么内在的问题吗?它按要求工作,但在边缘上的性能很差。我的测试用例在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种不同的管理异步操作的技术可能是错误的。:-)
发布于 2019-05-28 01:41:10
我之所以结束这个问题,是因为我已经将我的主要问题--使用边缘浏览器时的性能--隔离到了一个用于将SVG转换为PDF的库中,而不是我使用的承诺、setTimeout或异步/等待,但是对下面的其他发现的任何进一步的洞察力都是非常感谢的!
@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(...)中,并不允许浏览器在循环中做出任何响应。
https://stackoverflow.com/questions/56302004
复制相似问题