Проблемы с производительностью в Promises, setTimeout, async / await на Edge - PullRequest
2 голосов
/ 25 мая 2019

Есть ли что-то по сути неправильно в следующем смешанном использовании 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 голосов
/ 28 мая 2019

Я закрываю этот вопрос, потому что я выделил свою основную проблему - производительность при использовании браузера Edge - в библиотеку, которую я использую для преобразования SVG в PDF, а не для своего использования. обещаний, setTimeout или async / await, но мы будем благодарны за дальнейшее понимание дополнительных выводов, представленных ниже!

@ Предложения Берги очень ценятся, но я, вероятно, все еще что-то упускаю. Если я не включаю строки после 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(...), не позволяло браузеру реагировать вообще внутри цикла.

...