Pull to refresh

Comments 22

Доходчиво изложено, спасибо. Насколько я понимаю, у варианта с блокировкой кнопки также недостаток в том что шибко умный юзер может дергать API через Postman и тем самым обходить блок кнопки на фронте.

спасибо, рада! этот вариант тоже не назовешь случайным повтором )

В синхронном сценарии есть проблемка, между шагами 1 и 2 в браузерной реализации есть место для состояния гонки:

1. Пользователь нажимает кнопку Перевести
2. Кнопка становится неактивной
    Запрос уходит на сервер, интерфейс ждёт ответ

Обработчикам в js требуется небольшое время на то, чтобы сделать кнопку неактивной.
Престарелые мышки у пользователей могут выдавать несколько кликов вместо одного из-за эффекта дребезга контакта. Время между событиями составляет единицы милисекунд.

Описанный синхронный подход не защищает от этой гонки.

Вниманимательно слушаю почему эта конструкция не будет работать? 👀

button.addEventListener('click', () => {

  button.disabled = true; // 1. Сначала выключаем

  sendData();             // 2. Потом отправляем

});

Между кликом и button.disabled = true проходит ненулевое время, в этот промежуток времени возникает состояние гонки.

Синхронный код, пока блокировка не выполнится, дальше не пойдёт, что тут непонятного

Не понятно с чего вы взяли, что изменения DOM хоть как то влияют на события, которые уже находятся в очереди JS на обработку.

Пытаюсь найти банк, но тут ни слова, хотя есть пару где есть такая беда

Вы прошли собес в итоге? Вам сделали оффер?

в поиске, в переговорах, статьи пока пишу )

У вас алгоритм для идемпотентности некорректный. Если вы генерируете уникальный ключ на клиенте при нажатии кнопки, то повторные нажатия дадут разные уникальные ключи и пройдут две оплаты.

ключ будем генерить до отправки запроса, и если параметры запроса не меняются, то и ключ не изменится

Ну ка, какие у вас будут параметры, которые формируют ключ? Сумма, отправитель и получатель? Тогда точно такая же отправка средств будет заблокирована, хотя по факту это именно другой перевод.

Банально timestamp генерации формы даст уникальность

Да, но судя по схеме ТС ключ генерируется при нажатии кнопки, а не при формировании формы отправки.

две вкладки, открытые в одно и то же время, приведут к тому, что два разных перевода будут восприняты как один

С такой удачей лучше купить партию лотерейных билетов.

в асинхронном варианте вся проблема в том, кто решает новый это запрос или повторный.

если перезагрузили страницу и нажимаем перевод еще раз пока не получили ответ по первой операции, это будет новый запрос или повторный?

если надо выполнить подряд два одинаковых перевода(один и тот же получатель и сумма), то не получится ли что пользователю придет два подтверждения, а по факту перевод будет один?

Ключом уникальности, обычно, выступает форма (страница) + timestamp (до нескольких минут).

Если ключ уникальности одинаковый, значит это один и тот же платеж. Если разные - это разные платежи.

и как обычно это не правильно решение. А правильно - локально сохранять заявку на перевод, которая не потеряется при перезагрузке приложения, и автоматически ретраить ее доставку, пока она не дойдет до сервера.

Имхо на frontend совсем не стоит полагаться. Имхо стоит рассматривать начало действия не в момент когда клиент "подтверждает перевод", а в момент когда он выбирает опцию - "сделать перевод". Именно в этот момент должен создаваться ключ операции (причем тоже не на стороне клиента) и именно с этим ключом операция и будет "финализироваться" ровно один раз, сколько бы запросов не отправлял клиент на сервер. Это и обеспечит идемпотентность.

А чтобы создать ключ операции нам нужно иметь ключ операции создания ключа операции…

Sign up to leave a comment.

Articles