Обещание Retry Wrapper для Ember - PullRequest
0 голосов
/ 26 января 2019

У меня есть фрагмент кода Ember, который вызывает конечную точку API и заполняет массив при получении ответа (есть другие элементы, добавленные в массив независимо от вызова API. Я упустил нерелевантный код для простоты):

descriptor: Ember.computed("qParams", function(){
    let qParams = this.get("qParams");
    let data = new Ember.A();
    let callHomePromise = this.get("store").find('info-extractor', qParams)
    .then(item => { data.pushObject(item); });
    return data;
    })

Этот код работает нормально и выполняет то, для чего предназначен. Я хотел бы создать ретриер: в случае сбоя this.get("store").find из-за основного вызова AJAX, отвечающего, например, 401, я бы дал ему еще пару попыток. На основании этого ответа

https://stackoverflow.com/a/51332115/1518685

Я разработал следующую оболочку:

export default function (promiseFactory) {

  let retryChain = Ember.RSVP.reject();
  for (var count = 0; count < 3; count++) {
  retryChain = retryChain.catch(reason => {
      return new Ember.RSVP.Promise((resolver, rejector) => {
        promiseFactory().catch(r => {
        setTimeout(rejector.bind(null, reason), 1000);
      }).then(ok => { resolver(ok); })
      });
    });
  }

  return retryChain;
}

Который я выполняю следующим образом:

import retrier from 'project/utils/retrier';

//....

descriptor: Ember.computed("qParams", function(){
    let qParams = this.get("qParams");
    let data = new Ember.A();
    let callHomePromise = retrier(() => { 
         return this.get("store").find('info-extractor', qParams); 
        }).then(item => { data.pushObject(item); })
          .catch(reason => { /* do stuff with reason */});
    return data;
    })

Я смоделировал ошибочные запросы (установив неверную переменную qParams) и наблюдал, как несколько AJAX-запросов не выполнялись, и в конечном итоге постоянный сбой регистрировался в методе catch () после ретритера.

Однако, когда вызов успешен, обещание ретритера никогда не разрешается, и я не могу понять, почему?

Любая помощь будет принята с благодарностью.

1 Ответ

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

Эта часть кода

    return new Ember.RSVP.Promise((resolver, rejector) => {
      promiseFactory().catch(r => {
      setTimeout(rejector.bind(null, reason), 1000);
    })

никогда не вызывает resolver, поэтому он не может быть успешным и достигнет следующего then. Затем переместите следующее в выражение:

  retryChain = retryChain.catch(reason => {
    return new Ember.RSVP.Promise((resolver, rejector) => {
      promiseFactory().then(ok => { resolver(ok); }, r => {
        setTimeout(rejector.bind(null, reason), 1000);
      });
    });
  });
...