Александр Козлов

Александр Козлов

делаю Авторский Комикс

132subscribers

118posts

goals2
26 of 40 paid subscribers
Проведем комикс-баттл с судьями из числа платных подписчиков!
1 of 2

Асинхронная обработка форм

Занимаюсь давно обещанным обновлением текстового редактора на портале. С наскока сделать не получилось - постоянно натыкаюсь на технический долг, который так или иначе мешает подключению к сайту новых библиотек. Интересно, что большинство современных WYSIWYG-редакторов Markdown делаются под популярные фреймворки: React, Angular, Vue. Найти что-то стабильной под сайт, написанный на ванильном JS, не так то просто.
Пока закрываю техдолги, добавил на сайт функцию для асинхронной обработки форм. А ванильные HTML-формы на Авторском Комиксе используются много где. В чем суть проблемы: обработчик отправки формы (событие submit) синхронный, как и все другие обработчики в JS. Поэтому, если в момент отправки формы нам нужно в асинхронном режиме дозапросить какие-то данные, просто через await мы это сделать не можем, так как обработчик завершит свою работу раньше, чем дождется выполнения асинхронной функции.
Решение проблемы можно посмотреть в файле AsyncForm.js: предполагается, что все поля формы, которые требуют асинхронных действий перед отправкой формы имеют атрибут 'data-async-processing' и в поле с именем 'processAsync' содержат асинхронные функции, выполняющие необходимые операции. Если у формы есть такие поля, то в момент ее отправки, мы прервем обработку событий, выполним 'processAsync' где это необходимо, и только потом заново сэмулируем отправку формы. При этом эмуляция отправки формы происходит через HTMLFormElement.prototype.requestSubmit.call(form, evt.submitter); что гарантирует, что при наличии нескольких кнопок отправки формы будет сохранена именно та, которую нажал пользователь.
Если у вас есть более элегантное решение для асинхронной обработки событий в JS, в частности событий отправки формы, напишите об этом в комментариях.
Хм, любопытно. А что за асинхронные операции выполняют эти поля? Нельзя ли их как-то, хм-м-м, "засинхронить"? Например, с помощью тех же async/await можно сделать так, что вроде бы асинхронная функция будет выполняться синхронно, и в синхронном контексте.
Сцинк, привет! По поводу async/await - это распространенное заблуждение, они не делают код синхронным, просто скрывают работу с промисами под синтаксическим сахаром. По сути код остается асинхронным: 
Если ты хочешь использовать await внутри обработчика событий, то его придется делать асинхронным (async). А это значит, что обработчик будет возвращать объект Promise, не дожидаясь своего окончания.
Про синхронные операции, которые нужно выполнять при отправке формы, например, запрос рекапчи: 
Александр Козлов, да, проверил - и действительно, вызов функции async в обычной синхронной её не притормаживает.Ну тогда у меня нет идей лучше, чем описанная в посте. Да и вообще, по мне так там вполне годная идея описана, ты можешь добавлять асинхронные процессы для каждого поля отдельно, а хэндлить это будет одно централизованное место, и пространство для факапа вроде бы невелико. Может и не дохрена элегантно, но для костыля в целях совместимости - достаточно хорошее решение.
Subscription levels4

Базовый уровень

$2.57 per month
Для тех, кто хочет помочь в разработке и поддержке Авторского Комикса.

Продвинутый уровень

$6.5 per month
Для тех, кто хочет помочь в разработке и поддержке Авторского Комикса еще сильнее.

Золотой уровень

$12.9 per month
Для тех, кто хочет помочь в разработке и поддержке Авторского Комикса очень сильно.

Платиновый уровень

$39 per month
Для тех, кто хочет помочь в разработке и поддержке Авторского Комикса сверхсильно!
Go up