首页 > 解决方案 > Ember 的 Promise 重试包装器

问题描述

我有一段 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() 方法中捕获了永久失败。

但是,当调用成功时,retrier 承诺永远不会解决,我不知道为什么?

任何帮助将不胜感激。

标签: ember.jspromiseember.js-2

解决方案


这部分代码

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

从不调用解析器,因此它不可能成功并达到以下then. 然后将以下内容移动到这样的表达式中:

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

推荐阅读