Работа с несколькими пост-сбоями AJax от нескольких входов формы - PullRequest
0 голосов
/ 27 декабря 2018

Я работаю над приложением PHP для обслуживания вопросов с множественным выбором и текстовых вопросов.В коде Javascript, когда пользователь отвечает на вопрос, ajax submit отправляет ответ на сервер PHP.

Вот как это работает:

$('textarea,input').on('change',function postinput() {
  var name = $(this).attr('name');
  var value = $(this).val();
  var itemstr = name + "=" + value;
  $.ajax({
    url: window.location.href,
    data: itemstr,
    type: 'post'
  }).done(function(responseData) {
    console.log('Done: ', responseData);
  }).fail(function() {
    console.log('Failed');
  });
});

В настоящий момент он работает идеально, выполняя именно то, что должен.Сервер получает ответ и сохраняет его в базе данных.

Однако часть AJax моего решения должна быть намного более надежной.Что делать, если во время ответа пользователя на вопрос появляется временная ошибка сети?Или, что еще хуже, что если сеть отключится на минуту, две или даже дольше?Или что если сервер выйдет из строя?Мне нужно сообщить пользователю, что есть проблема, и либо повторить попытку автоматически, либо дать ему кнопку, чтобы нажать кнопку, чтобы повторить попытку.

Каков наилучший способ обработки этих ошибок в коде ajax?Ответ, конечно, заключается в том, чтобы заполнить блок «fail», но я не совсем уверен, как это должно выглядеть.

Так как каждое изменение формы инициирует ответ Ajax, я не хочу, чтобы каждое из них по отдельности повторялось, или это могло бы потенциально загрузить сервер, когда он возвращается.Как блок сбоя может отслеживать эти неудачные отправки из всех отправок и периодически повторять попытку?

1 Ответ

0 голосов
/ 27 декабря 2018

Из сбоя можно почерпнуть несколько вещей

  1. Код состояния
  2. Текст статуса (причина, по которой он вышел из строя)

Мыможет генерировать уникальный ключ и использовать его в качестве идентификатора ошибки.Это может работать:

function guid() {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
      .toString(16)
      .substring(1);
  }
  return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}

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

$.ajax({
    …
  }).done(function(responseData) {
    …
  }).fail(function(data) {
    const { statusText, status } = data;
    addToFailureQueue({
      requestId: guid(),
      failureText: statusText,
      statusCode: status
    });
  });

Используя функцию setInterval, вы можете опросить, проверяячтобы увидеть, если очередь пуста.Если нет, вы можете перебрать и повторно инициализировать каждый неудачный запрос.Если повторный запрос успешно выполнен, удалите его из очереди.

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

let failureQueue = [];

// Generates a unique string of characters suitable for a key
function guid() {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
      .toString(16)
      .substring(1);
  }
  return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}

function showOutput(obj) {
  const output = $('.output');
	for (let o in obj) {
    if (obj.hasOwnProperty(o)) {
    	output.append(`<li><strong>${o}</strong>: ${obj[o]}</li>`) 
    }
  }
}

function addToFailureQueue(obj) {
	failureQueue.push(obj);
  showOutput(obj);
} 

function makeFakeRequest() {
  $.ajax({
    url: window.location.href,
    data: '',
    type: 'post'
  }).done(function(responseData) {
    console.log('Done: ', responseData);
  }).fail(function(data) {
    const { statusText, status } = data;
    addToFailureQueue({
      requestId: guid(),
    	failureText: statusText,
      statusCode: status
    });
  });
}

$('.myButton').on('click', makeFakeRequest);
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

button {
  background: #0084ff;
  border: none;
  border-radius: 5px;
  padding: 8px 14px;
  font-size: 15px;
  color: #fff;
}

.output {
  background-color: #fff;
}

.output:not(:empty) {
  padding: 1rem;
}

.output li {
  margin: 0;
  padding: 0 0 .5rem;
  list-style: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<button class="myButton">Make fake request</button>
<ul class="output"></ul>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...