Давайте посмотрим на лес сначала, прежде чем смотреть на деревья.
Здесь есть много информативных ответов с большими подробностями, я не буду повторять ни одного из них. Ключ к программированию в JavaScript имеет сначала правильную ментальную модель общего исполнения.
Хорошие новости заключается в том, что, если вы хорошо понимаете этот момент, вам никогда не придется беспокоиться о гоночных условиях. Прежде всего вы должны понимать, как вы хотите упорядочить свой код как по существу ответ на разные дискретные события, и как вы хотите объединить их в логическую последовательность. Вы можете использовать обещания или новые асинхронные / ожидающие более высокие уровни в качестве инструментов для этой цели, или вы можете откатывать свои собственные.
Но вы не должны использовать какие-либо тактические инструменты для решения проблемы, пока вам не понравится актуальная проблемная область. Нарисуйте карту этих зависимостей, чтобы знать, что нужно запускать, когда. Попытка ad-hoc подхода ко всем этим обратным вызовам просто не поможет вам.
Обновление:
Я не уверен, когда или если лицензия была изменена для библиотеки iText # , но она лицензирована в AGPL , которая означает, что он должен быть лицензирован, если он включен в продукт с закрытым исходным кодом. Вопрос не требует (в настоящее время) бесплатных или открытых библиотек. Всегда нужно исследовать тип лицензии любой библиотеки, используемой в проекте.
Я успешно использовал iText # в .NET C # 3.5; это порт библиотеки Java с открытым исходным кодом для генерации PDF, и это бесплатно.
Существует пакет NuGet , доступный для версии iTextSharp версии 5 и официальной документации разработчика / g4], а также примеры C # , можно найти на itextpdf.com
В моей работе используется PDF-генератор Winnovative (мы использовали его главным образом для преобразования HTML в PDF, но вы можете сгенерировать его и другими способами)
Недавно я завершил проект, в котором мы использовали Aspose.Pdf для .NET . Я думаю, было неплохо работать и хорошо стоить, если iTextSharp не для вас.