AIO SDK Form: Submit Promises и Before Submit Promises
Назначение
AIO SDK Form предоставляет два механизма для асинхронной пользовательской логики вокруг отправки формы:
beforeSubmitPromises- выполняются до начала реальной отправки формыsubmitPromises- выполняются во время отправки и могут отслеживать результат реальной отправки черезformPromise
Оба принимают массив функций, и каждая функция должна возвращать Promise.
Что такое Promise в JavaScript
Promise это объект, который представляет результат асинхронной операции.
У Promise три состояния:
pending- операция ещё выполняетсяfulfilled- операция завершилась успешноrejected- операция завершилась с ошибкой
Базовый пример
const promise = new Promise((resolve, reject) => {
const ok = true;
if (ok) {
resolve("success");
} else {
reject("error");
}
});Обработка результата
promise
.then((result) => {
console.log("Success:", result);
})
.catch((reason) => {
console.log("Error:", reason);
})
.finally(() => {
console.log("This block always runs");
});Что делают resolve и reject
resolve(value)- завершает Promise успешноreject(reason)- завершает Promise с ошибкой
Как Promise используются в AIO SDK Form
Форма использует Promise в двух местах:
beforeSubmitPromises
Используются для логики, которая должна завершиться до фактической отправки формы.
Примеры:
- подтверждение / модальное окно перед отправкой
- дополнительная валидация
- обязательное действие пользователя перед отправкой
- trigger перед fetch
submitPromises
Используются для логики, которая должна выполняться вокруг уже начатой отправки.
Примеры:
- модальное окно ожидания
- собственный UI для успеха / ошибки
- смена текста модального окна, пока запрос выполняется
- собственный редирект после ответа сервера
Сигнатуры колбэков
beforeSubmitPromises
(ut, aioExchange, config) => PromiseАргументы
ut-UTILSaioExchange- объект exchange, можно использовать дляtriggerconfig- текущая конфигурация формы
submitPromises
(ut, formPromise, aioExchange, config) => PromiseАргументы
ut-UTILSformPromise- Promise результата реальной отправки формыaioExchange- объект exchangeconfig- текущая конфигурация формы
Как работают beforeSubmitPromises
Общая логика
При отправке формы SDK:
- собирает данные формы
- проверяет номер телефона
- блокирует форму
- запускает все
beforeSubmitPromises - ждёт, пока все они завершатся успешно
- только после этого запускает реальный
fetch
Что означает resolve()
Если колбэк внутри beforeSubmitPromises вызывает resolve(), это означает:
- этот шаг завершился успешно
- форма может продолжить процесс отправки
Что означает reject()
Если колбэк внутри beforeSubmitPromises вызывает reject(), это означает:
- отправка остановлена
- реальный
fetchне запускается - ошибка показывается через
submitErrorCb
Важный вывод
beforeSubmitPromises это блокирующий этап перед отправкой.
Как работают submitPromises
Общая логика
После успешного завершения beforeSubmitPromises SDK:
- создаёт внутренний
formPromise - запускает все
submitPromises - сразу же запускает реальный
fetch
Что такое formPromise
formPromise представляет результат реальной отправки формы.
При успешной отправке:
formPromise.then((response) => {
// response = { success: true, url: "..." }
});При неудачной отправке:
formPromise.catch((reason) => {
// reason = rejectedMessage
});Что означает resolve() внутри submitPromises
resolve() завершает только тот Promise, который вернул ваш собственный колбэк.
Он не:
- запускает отправку
- отменяет отправку
- управляет fetch
- управляет
submitErrorCb
Что означает reject() внутри submitPromises
reject() отклоняет только ваш собственный Promise.
Он не:
- отменяет реальную отправку формы
- останавливает fetch
- автоматически запускает обработку ошибки формы
Важный вывод
submitPromises это неблокирующая обёртка вокруг отправки: она может отслеживать formPromise, но не управляет тем, будет ли форма отправлена на самом деле.
Порядок отправки формы
Полный порядок отправки такой:
- пользователь нажимает кнопку отправки
- SDK вызывает
preventDefault() - SDK собирает данные формы
- SDK проверяет номер телефона
- SDK вызывает
disableForms() - SDK запускает
beforeSubmitPromises - если все
beforeSubmitPromisesзавершились черезresolve():- создаётся внутренний
formPromise - запускаются
submitPromises - запускается реальный
fetch
- создаётся внутренний
- если сервер возвращает
success: true:formPromiseразрешается- вызывается
successForms(...) - затем вызывается
successFn(url)
- если сервер возвращает ошибку, невалидный JSON или
success: false:formPromiseотклоняется сrejectedMessage- вызывается
submitErrorCb
Когда использовать beforeSubmitPromises
Используйте beforeSubmitPromises, когда нужно:
- разрешить или заблокировать отправку
- показать подтверждение перед отправкой
- дождаться обязательного действия пользователя
- выполнить обязательную логику до отправки формы
Пример: подтверждение отправки
<script>
window.aioBus = window.aioBus || [];
window.aioBus.push({
type: "config",
config: {
form: {
beforeSubmitPromises: [
(ut, aioExchange, config) => new Promise((resolve, reject) => {
if (confirm("Submit the form?")) {
resolve();
} else {
reject();
}
})
]
}
}
});
</script>Пример: trigger перед отправкой
<script>
window.aioBus = window.aioBus || [];
window.aioBus.push({
type: "config",
config: {
form: {
beforeSubmitPromises: [
(ut, aioExchange, config) => new Promise((resolve, reject) => {
aioExchange.trigger("ad_name", "FORM YES");
resolve();
})
]
}
}
});
</script>Пример: модальное окно перед отправкой
<script>
window.aioBus = window.aioBus || [];
window.aioBus.push({
type: "config",
config: {
form: {
beforeSubmitPromises: [
(ut, aioExchange, config) => new Promise((resolve, reject) => {
const modal = document.getElementById("before-promise-modal");
ut.openModal({
nativeElement: modal,
resolve: resolve,
reject: reject,
countDown: 5,
countDownStyle: "minutes",
countDownCb: () => {
ut.closeModal(modal);
resolve();
}
});
})
]
}
}
});
</script>Когда использовать submitPromises
Используйте submitPromises, когда нужно:
- показать UI ожидания во время отправки
- обработать результат успеха / ошибки через
formPromise - обновить содержимое модального окна после ответа сервера
- построить собственный сценарий успеха или ошибки
Пример: простое модальное окно ожидания
<script>
window.aioBus = window.aioBus || [];
window.aioBus.push({
type: "config",
config: {
form: {
successFn: (url) => null,
submitPromises: [
(ut, formPromise, aioExchange, config) => new Promise((resolve, reject) => {
const modal = document.getElementById("submit-modal");
formPromise
.then((response) => {
modal.querySelector("h1").innerText = "Success: " + response.url;
})
.catch((reason) => {
modal.querySelector("h1").innerText = "Failed: " + reason;
});
ut.openModal({
nativeElement: modal,
countDown: 3,
countDownStyle: "minutes",
countDownCb: () => {
resolve();
}
});
})
]
}
}
});
</script>Пример: модальное окно успеха / ошибки
<script>
window.aioBus = window.aioBus || [];
window.aioBus.push({
type: "config",
config: {
form: {
successFn: (url) => null,
submitPromises: [
(ut, formPromise, aioExchange, config) => new Promise((resolve, reject) => {
const waitingModal = document.getElementById("submit-promise-modal");
const successModal = document.getElementById("submit-success-modal");
const failedModal = document.getElementById("submit-failed-modal");
formPromise
.then((response) => {
ut.closeModal(waitingModal);
ut.openModal({ nativeElement: successModal });
})
.catch((reason) => {
ut.closeModal(waitingModal);
ut.openModal({ nativeElement: failedModal });
});
ut.openModal({
nativeElement: waitingModal,
countDown: 10,
countDownStyle: "minutes",
countDownCb: () => {
resolve();
}
});
})
]
}
}
});
</script>Пример: собственный редирект после успеха
<script>
window.aioBus = window.aioBus || [];
window.aioBus.push({
type: "config",
config: {
form: {
successFn: (url) => null,
submitPromises: [
(ut, formPromise, aioExchange, config) => new Promise((resolve, reject) => {
formPromise
.then((response) => {
setTimeout(() => {
window.location.href = response.url;
}, 2000);
})
.catch((reason) => {
console.log("Submit failed:", reason);
});
resolve();
})
]
}
}
});
</script>Разница между beforeSubmitPromises и submitPromises
| Параметр | beforeSubmitPromises | submitPromises |
|---|---|---|
| Когда выполняется | До реальной отправки | Во время отправки |
| Блокирует отправку формы | Да | Нет |
| Может остановить fetch | Да | Нет |
Получает formPromise | Нет | Да |
| Подходит для подтверждения / предварительной проверки | Да | Нет |
| Подходит для UI отправки | Ограниченно | Да |
Поведение нескольких Promise
И beforeSubmitPromises, и submitPromises обрабатываются через Promise.all(...).
Это означает:
- все Promise в массиве запускаются параллельно
- это не последовательная цепочка
Пример
beforeSubmitPromises: [
promise1,
promise2,
promise3
]Все три колбэка запустятся одновременно.
Если нужна последовательная логика
Если шаги должны выполняться строго один за другим, лучше объединить их в один Promise.
beforeSubmitPromises: [
(ut, aioExchange, config) => new Promise(async (resolve, reject) => {
try {
await step1();
await step2();
await step3();
resolve();
} catch (e) {
reject(e);
}
})
]Работа с successFn
После успешной отправки SDK вызывает successFn(json.url).
По умолчанию:
successFn: (url) => window.top.location.replace(url)Если нужен собственный сценарий успеха, обычно его переопределяют так:
successFn: (url) => nullПосле этого логику редиректа можно обрабатывать вручную внутри submitPromises.
Шаблоны для повторного использования
Шаблон beforeSubmitPromises
beforeSubmitPromises: [
(ut, aioExchange, config) => new Promise((resolve, reject) => {
try {
// Logic before submit
resolve();
} catch (e) {
reject(e);
}
})
]Шаблон submitPromises
submitPromises: [
(ut, formPromise, aioExchange, config) => new Promise((resolve, reject) => {
try {
formPromise
.then((response) => {
// success
})
.catch((reason) => {
// failed
});
resolve();
} catch (e) {
reject(e);
}
})
]Итоги
beforeSubmitPromises
Используются для обязательной логики до отправки формы.
- блокируют отправку
resolve()разрешает отправкуreject()останавливает отправку
submitPromises
Используются для логики вокруг отправки формы.
- не блокируют отправку
- получают
formPromise - подходят для собственного UI и собственных сценариев успеха / ошибки
formPromise
Это Promise результата реальной отправки формы.
then(response)-> успешная отправкаcatch(reason)-> неудачная отправка