Реализация VanillaJS Promise для замены события jQuery notify / progress - PullRequest
0 голосов
/ 29 декабря 2018

В настоящее время я использую объект $.Deferred() для отправки сообщений.

Когда сервер возвращает ошибку, я использую notify и повторяю попытку до тех пор, пока она не будет выполнена или не завершится X раз.

Я хочу отказаться от использования jQuery и перейти к параметрам, связанным с ES6.

Я знаю, как использовать Promise(), но его можно отклонить или разрешить, но не оба.

Есть идея получше?

Текущий код:

var def = $.Deferred(),
  data = {
    iTries: 0,
    ....
  };

$.ajax({
  type: "POST",
  url: "POST",
  data: data,
  timeout: 15000,
  success: d => def.resolve(d);,
  error: function(vSocket, status, error) {
    def.notify('error'); // this I want to replace
    data.iTries++;

    //try again
    if (data.iTries < 40) window.setTimeout(function() {
      DoAgain(data, def).then(q => def.resolve(q));
    }, 9000);
    else {
      def.reject();
    }
  }
  else {
    if (data.iTries < 20) window.setTimeout(function() {
      Poll.AjaxPoll(data, def).then(q => def.resolve(q));
    }, 30000);
  }
}
});

Ответы [ 2 ]

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

Из вашего кода видно, что вы используете ES6 (вы используете функции стрелок).Вы можете следовать рекурсивному подходу с функциями и обещаниями стрелки es6, это может быть что-то вроде этого:

doAjaxRequest(data) {
    fireAPICall(data).then(response => { // fireAPICall is a method that fires the post request and returns the response received from server
        if(response.status == 200) { // success (this if statement is optional)
            // handle success
            let d = response.data;
        }
    }).catch(error => { // failure
        data.iTries++;
        if(data.iTries < 40) {
            window.setTimeout(() => {doAjaxRequest(data)}, 9000); // try again
        } else if(data.iTries < 20) {
            window.setTimeout(() => {doAjaxRequest(data)}, 30000); // try again
        }
    });
}

Для метода fireAPICall вы можете использовать любой основанный на обещаниях http-клиент, такой как axios или Fetch API , здесь я использую axios:

fireAPICall(data) {
    return axios.post("url", data);
}

Обновление : если вы хотите обрабатывать как reject/failure событие, так и notify/progress событий, для этого потребуется совместная работа на стороне сервера.Вы можете заставить свой сервер возвращать код состояния 202 (или любой другой более подходящий код состояния) в случае события прогресса (пока не готово), и вы можете обработать это в обратном вызове .then():

doAjaxRequest(data) {
    fireAPICall(data).then(response => { // fireAPICall is a method that fires the post request and returns the response received from server
        if(response.status === 202) { // notify/progress event
            data.iTries++;
            if(data.iTries < 40) {
                window.setTimeout(() => {doAjaxRequest(data)}, 9000); // try again
            } else if(data.iTries < 20) {
                window.setTimeout(() => {doAjaxRequest(data)}, 30000); // try again
            } else {
                return Promise.reject('poll eneded with no success'); // exceeded maximum number of times for polling, so reject. This will invoke the catch callback method with this error
            }
        } else { // handle success
            let d = response.data;
        }
    }).catch(error => { // reject/failure for some other reason
        // handle error
    });
}
0 голосов
/ 29 декабря 2018

Как вы говорите, обещание может быть выполнено только один раз .(Это также верно для $.Deferred в jQuery, который [сейчас] в основном похож на обещание.)

Повторяющиеся уведомления не используются для обещаний.Вместо этого вам нужен какой-нибудь источник событий или система публикации / подписки (есть такие же очень маленькие для jQuery, такие как этот [не одобрение]), или даже простообратный вызов, которому вы звоните с обновлениями прогресса.

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