JQuery AJAX связь между успехом и .then - PullRequest
0 голосов
/ 23 февраля 2019

Я пытаюсь решить очень простую проблему, но не могу понять.У меня есть следующий код:

<button onclick="run()">TEST</button>
<script>
    var counter = 0;
    function test() {           
        return $.ajax({
           url: "https://127.0.0.1:4432",
           success: function(html){
              console.log('success! test');
           },
           error: function() {
            if (counter++ < 3) {
                console.log("Retrying");
                $.ajax(this);
                return;
            }           
            console.log('ERROR! test');
           }
        });
    }   

    function run() {
        test()
        .then(
            function(){console.log('finished ALL OK')}, 
            function() {console.log('finished all ERROR')
        ;});

    }


</script>

Чего я хочу добиться, так это то, что после нажатия на кнопку запрос AJAX будет отправлен на сервер.В случае сбоя AJAX запрос будет повторен.Только после того, как все повторные попытки будут завершены, будет вызван успех или неудача в функции ".then".

В этот момент код ведет себя так, что вызов AJAX повторяется три раза, но "Обработчик .then () "вызывается сразу после первого сбоя.

В консоли браузера это выглядит так:

Console of the browser

После всех повторных попыток я хотел бы видеть текст «Закончена вся ОШИБКА» в конце.

Надеюсь, что это имеет смысл, и я буду благодарен за любую помощь.

Ответы [ 3 ]

0 голосов
/ 23 февраля 2019

Все, что находится в методе success, не повлияет на .then в том же объекте jqXHR.Для цепочки, которую вы ищете, рассмотрите возможность использования only .then s и .catch es вместо:

function test() {
  let counter = 0;
  const get = () => $.ajax({ url: "https://127.0.0.1:4432" })
  .then((html) => {
    console.log('success');
  })
  .catch((err) => {
    if (counter++ < 3) {
      console.log("Retrying");
      return get();
    }
    console.log('ERROR! test');
    throw new Error();
  });
  return get();
}

test()
  .then(
  function() {
    console.log('finished ALL OK')
  },
  function() {
    console.log('finished all ERROR');
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
0 голосов
/ 23 февраля 2019

Одним из возможных решений является завершение всей операции в Promise , хотя вам может потребоваться полифилл для 100% поддержки браузера.это будет выглядеть примерно так:

function test() {
    return new Promise(function(resolve, reject) {
        var counter = 0;
        $.ajax({
            url: "https://127.0.0.1:4432",
            success: function(html){
                console.log('success! test');
                resolve(html);
            },
            error: function() {
                if (counter++ < 3) {
                    console.log("Retrying");
                    $.ajax(this);
                }
                console.log('ERROR! test');
                reject('retries exceeded');
            }
        });
    });
}

function run() {
    test().then(
        function() { console.log('finished ALL OK'); },
        function() { console.log('finished all ERROR'); }
    );
}
0 голосов
/ 23 февраля 2019

function test(counter, $existingDeferred) {
        var $deferred = $existingDeferred || $.Deferred();
        
        $.ajax({
           url: "https://127.0.0.1:4432",
           success: function(html){
              console.log('success! test');
              $deferred.resolve(arguments);
           },
           error: function() {
            console.log('ERROR! test');
            
            if (counter < 3) {
                console.log("Retrying");
                test(++counter, $deferred);
            } else {
                $deferred.reject(arguments);
            }
          }
        });
        
        return $deferred;
    }   

    function run() {
        test(0)
        .then(
            function(){console.log('finished ALL OK')}, 
            function() {console.log('finished all ERROR')
        ;});

    }

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

  • Передача в счетчике счетчика и, необязательно, вторичная отсроченная
  • Если у нас нет отсроченного, создайте его.
    • Выполнить запрос Ajax
    • В случае успеха разрешить отложенное
    • Если ошибка
    • Если попытки не были исчерпаны, выполнить метод с увеличенным счетчикоми существующее отложенное
    • В противном случае отклоните отложенное, чтобы обозначить завершение процесса
  • Возвратите отложенное, которое будет разрешено при успехе, или отклонено, когда все попытки исчерпаны.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...