Блок транзакций не возвращает правильный номер [дубликат]

Давайте посмотрим на лес сначала, прежде чем смотреть на деревья.

Здесь есть много информативных ответов с большими подробностями, я не буду повторять ни одного из них. Ключ к программированию в JavaScript имеет сначала правильную ментальную модель общего исполнения.

  1. Ваша точка входа (ов) выполняется в результате события. Например, в браузер загружается тег сценария с кодом. (Соответственно, поэтому вам, возможно, придется заботиться о готовности страницы запускать ваш код, если он требует, чтобы элементы dom были сконструированы первыми и т. Д.)
  2. Ваш код выполняется до завершения, однако многие асинхронные вызовы, которые он делает, без выполнения каких-либо ваших обратных вызовов, включая запросы XHR, установку тайм-аутов, обработчиков событий dom и т. д. Каждый из этих обратных вызовов, ожидающих выполнения, будет находиться в очереди, ожидая, что их очередь будет запущена после других событий
  3. Каждый отдельный обратный вызов XHR-запроса, установленного таймаута или dom события после вызова будет завершен.

Хорошие новости заключается в том, что, если вы хорошо понимаете этот момент, вам никогда не придется беспокоиться о гоночных условиях. Прежде всего вы должны понимать, как вы хотите упорядочить свой код как по существу ответ на разные дискретные события, и как вы хотите объединить их в логическую последовательность. Вы можете использовать обещания или новые асинхронные / ожидающие более высокие уровни в качестве инструментов для этой цели, или вы можете откатывать свои собственные.

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

5
задан webduvet 2 March 2015 в 14:31
поделиться

1 ответ

Вернув undefined в ваш блок if( ... === null ), вы прерываете транзакцию. Таким образом, он никогда не посылает попытку на сервер, никогда не понимает, что локально кэшированное значение не совпадает с удаленным, и никогда не повторяет с обновленным значением (фактическое значение с сервера).

Это подтверждается тот факт, что committed является false, а ошибка - null в вашей функции успеха, которая возникает, если транзакция прерывается.

Сделки работают следующим образом:

  • передать локально кэшированное значение в функцию обработки, если вы никогда не извлекали эти данные с сервера, тогда локально кэшированное значение null (наиболее вероятное удаленное значение для этого пути)
  • get возвращаемое значение из функции обработки, если это значение undefined прервать транзакцию, в противном случае создать хеш текущего значения (null) и передать это и новое значение (возвращаемое функцией обработки) на сервер
  • , если локальный хеш соответствует текущему хэшу сервера, это изменение применяется, и сервер возвращает результат успеха
  • , если транзакция сервера не применяется , сервер возвращает новое значение, клиент затем снова вызывает функцию обработки с обновленным значением с сервера до успешного
  • , когда он в конечном счете успешный, и возникает неустранимая ошибка, или транзакция прерывается (возвращая неопределенные из функция обработки), то метод успеха вызывается с результатами.

Итак, чтобы сделать эту работу, очевидно, что вы не можете прервать транзакцию по первому возвращенному значению.

Одно решение для достижения одного и того же результата - хотя оно связано и не является таким же результативным или подходящим, как просто использование транзакций, как было разработано, - было бы обернуть транзакцию в обратном вызове once('value', ...), что убедитесь, что он локализован локально перед запуском транзакции.

20
ответ дан Kato 23 August 2018 в 22:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: