Edge 上的 Promises、setTimeout、async/await 的性能问题
Performance issue with Promises, setTimeout, async/await on Edge
以下混合使用 asnyc/await、promise 和 setInterval 是否有任何固有的错误?它按预期工作,但在 Edge 上的性能很糟糕。我的测试用例在 Chrome 中运行大约 3.5 秒,但在 Edge 中运行超过 2 分钟。请注意,这是来自 TypeScript class.
的方法
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 种不同的技术来管理异步操作可能是错误的。 :-)
我关闭这个问题是因为我已经将我的主要问题——使用 Edge 浏览器时的性能——隔离到我用来转换 SVG 的库到 PDF,而不是我对 promises、setTimeout 或 async/await 的使用,但对以下其他发现的任何进一步见解表示赞赏!
非常感谢@Bergi 的建议,但我可能仍然遗漏了一些东西。如果我不在 then()
中包含 await new Promise(...)
之后的行,我的循环会在生成 PDF 页面的内容之前完成,这会导致接下来的步骤 -- exporting完整的 PDF 内容作为字符串并保存到磁盘——失败。我需要此循环同步完成,以便我以正确的顺序获取所有 PDF 内容。我使用 new Promise(resolve => setTimeout(resolve, 0))
的唯一原因是稍微提高浏览器在循环期间的响应能力,它的工作原理与原始 post.
中所示的非常相似
我确实从 then
的回调中删除了 async
并切换到 exportSvg
函数的同步版本并且它运行良好。简单地等待对 exporter.exportSvgAsync
的调用而不将其包含在 await new Promise(resolve => setTimeout(resolve, 0)).then(...)
中并不允许浏览器在循环内完全响应。
以下混合使用 asnyc/await、promise 和 setInterval 是否有任何固有的错误?它按预期工作,但在 Edge 上的性能很糟糕。我的测试用例在 Chrome 中运行大约 3.5 秒,但在 Edge 中运行超过 2 分钟。请注意,这是来自 TypeScript class.
的方法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 种不同的技术来管理异步操作可能是错误的。 :-)
我关闭这个问题是因为我已经将我的主要问题——使用 Edge 浏览器时的性能——隔离到我用来转换 SVG 的库到 PDF,而不是我对 promises、setTimeout 或 async/await 的使用,但对以下其他发现的任何进一步见解表示赞赏!
非常感谢@Bergi 的建议,但我可能仍然遗漏了一些东西。如果我不在 then()
中包含 await new Promise(...)
之后的行,我的循环会在生成 PDF 页面的内容之前完成,这会导致接下来的步骤 -- exporting完整的 PDF 内容作为字符串并保存到磁盘——失败。我需要此循环同步完成,以便我以正确的顺序获取所有 PDF 内容。我使用 new Promise(resolve => setTimeout(resolve, 0))
的唯一原因是稍微提高浏览器在循环期间的响应能力,它的工作原理与原始 post.
我确实从 then
的回调中删除了 async
并切换到 exportSvg
函数的同步版本并且它运行良好。简单地等待对 exporter.exportSvgAsync
的调用而不将其包含在 await new Promise(resolve => setTimeout(resolve, 0)).then(...)
中并不允许浏览器在循环内完全响应。