javascript AJAX вызов, вызывающий проблемы с синхронизацией - PullRequest
0 голосов
/ 03 августа 2020

Программа A имеет форму, которая отправляется программе B. Форма программы A имеет вход:

<input type = 'hidden' name = 'token' id = 'token' value = ''> 

Значение устанавливается в javascript функции tkn (), которая вызывается программой A Вызов:

<input type    = 'button'
       value   = 'continue'                  
       onclick = 'tkn()'>

Функция tkn () вызывает функцию API, которая возвращает токен. Функция обратного вызова обрабатывает успех или неудачу вызова. В случае успеха обратный вызов выполняет

document.getElementById('token').value = response.id;

, а затем отправляет программу A

var theform = document.getElementById('token');
alert('theform is ' + theform);
theform.submit();

Обратите внимание на предупреждение, которое было помещено туда во время отладки, чтобы убедиться, что форма была правильно подобран перед отправкой.

Пока есть оповещение, все в порядке. Программа A передается программе B, токен проходит в B и делает все, что от него требуется.

Однако, если предупреждения нет, процедура завершается ошибкой, потому что токен передается в программу B как пробел.

Я нашел здесь объяснение проблемы, а также решение, которое я не понимаю: функция не работает правильно, если нет предупреждения . Очевидно, это проблема времени, потому что AJAX асинхронный. В предупреждении указывается время вызова AJAX.

Он предлагает решение - предоставить обратный вызов, в котором «вы выполните необходимые действия». У меня есть функция обратного вызова, но я не знаю, какие «необходимые действия» она должна предпринять для обеспечения завершения вызова AJAX. Вот обратный вызов:

function tokenHandler( status, response ){

// (ie. if the "error" key exists in the response).
if (response.hasOwnProperty( "error" )){

alert(  "Something went wrong! + response.error.message);
return;
}

else{
  document.getElementById('token').value = response.id;
}

}//function tokenhandler

Может ли кто-нибудь просветить меня о том, какие «необходимые действия» должна предпринять функция обратного вызова, чтобы убедиться, что вызов AJAX завершен?

В комментариях это Предполагается, что размещение

document.getElementById('token').value = response.id;

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

Есть ли у кого-нибудь другие предложения?

Вызов API:

Stripe.createToken(
  {
    number: cardno, 
    exp_month: emth, 
    exp_year: eyr, 
    cvc: cvv, 
    address_zip: '19004' 
  }, 
  amount,
  tokenHandler,);

A SOLUTION HAS BEEN FOUND.  I put the submit into the callback function instead of in the main tkn() function.  That fixed the problem.  So after all it is a timing problem, but I think it is between the callback function and the main function.  I assumed the submit wouldn't happen until the callback was finished, but apparently that is not the case. 

1 Ответ

0 голосов
/ 03 августа 2020

В ссылке SO, которую вы нам дали, ответ говорит, что alert() приостановил выполнение кода. Это заставляет код работать, потому что AJAX не выполняется синхронно, что означает, что код не ожидает вызова AJAX для fini sh. Следовательно, код и AJAX выполняются вместе, а AJAX не вернул результат, когда ваш код завершил работу. Но alert() s временно останавливает выполнение кода, пока вы не нажмете кнопку «Готово», так что AJAX успевает завершить sh. Добавьте весь свой код JS, чтобы я увидел, как его можно исправить. Я отредактирую это, как только вы это сделаете. Вам нужно поместить свой код в обратный вызов AJAX. Пример:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
       // Code here
    }
};
xhr.open("GET", "filename", true);
xhr.send();

Возможно, вы могли бы удалить свой onclick и добавить прослушиватель событий в // Code here. Пример:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
       document.getElementById("YourInput").addEventListener("click", function() {
           var theform = document.getElementById('token');
           alert('theform is ' + theform);
           theform.submit();
       });
    }
};
xhr.open("GET", "filename", true);
xhr.send();
...