Promises,setTimeout,Edge上的异步/等待的性能问题

时间:2019-05-25 05:28:24

标签: typescript promise async-await es6-promise

以下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种不同的技术来管理异步操作可能是错误的。 :-)

1 个答案:

答案 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(...)中并不能使浏览器在循环内完全响应。