Блок транзакций ошибочен Return [duplicate]

Краткий ответ: ваш метод foo() возвращается немедленно, а вызов $ajax() выполняется асинхронно после возврата функции . Проблема заключается в том, как и где сохранить результаты, полученные при вызове async, после его возврата.

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

function foo(result) {
    $.ajax({
        url: '...',
        success: function(response) {
            result.response = response;   // Store the async result
        }
    });
}

var result = { response: null };   // Object to hold the async result
foo(result);                       // Returns before the async completes

Обратите внимание, что вызов foo() ] все равно не вернут ничего полезного. Однако результат асинхронного вызова теперь будет сохранен в result.response.

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 в 21:56
поделиться