如何在当时拒绝承诺

时间:2017-05-24 21:40:22

标签: javascript ember.js promise es6-promise

如果承诺中的任何人以干净的方式失败,我希望能够拒绝整个承诺链。我想"赶上"这种拒绝并发送错误通知。我已经实现了以下代码:

let reportMetaData = api.ajaxGet(api.buildV3EnterpriseUrl('reports' + '/' + params.report_id))
  .catch(error => {
    if (error.status === constants.HTTP_STATUS.GATEWAY_TIMEOUT) {
      this.notify.error(this.translate('reports.report_timedout'), this.translate('reports.report_timedout_desc'));
    } else {
      this.send('error', error);
    }
  });

let aggregateData = reportMetaData.then(success => {
  try {
    return api.xmlRequest('GET', success.aggregationUrls.elements[0].url);
  } catch (error) {
    return Promise.reject();
  }
}).then(rawData => {
  try {
    return JSON.parse('{' + rawData + '}');
  } catch (error) {
    return Promise.reject();
  }
}, error => Promise.reject(error));

let aggregateReport = aggregateData.then(data => {
  if (!data || !data.report) {
    return Promise.reject();
  }
  return data.report;
}).catch(error =>{ 
    this.notify.error(this.translate('reports.report_timedout'), error); 
});

正如你所看到的,它是超级混乱的。有没有办法可以简化这个?如果有人承诺失败,我想要最简单的方法来拒绝整个承诺失败。我如何从then函数中做到这一点?此外,似乎抛出的错误一直冒泡到chrome控制台作为未捕获的错误。为什么即使我抓住它也会冒泡?

3 个答案:

答案 0 :(得分:1)

您需要使用Promise.all()并提供promises数组作为输入参数。 如果其中一项承诺失败,所有承诺都将无法解决。 这里的文档:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

这里有关于SO的帖子,你可以在这里阅读它们:

When to use promise.all()?

答案 1 :(得分:0)

尝试汇总Promise.all(iterable)下的所有内容。

更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

如果这不是您想要的,请查看Bluebird - 功能齐全的promise库。 Here

更新:如果您想要拒绝整个承诺,如果函数内的任何承诺失败,请尝试实现:

throw validationError;

希望它有效。

答案 2 :(得分:0)

您可以使用异步函数来清理一些东西。我想你可以用以下内容替换你的代码。

async function processDataAndReport() {
  try {
    const data = await api.ajaxGet(api.buildV3EnterpriseUrl('reports' + '/' + params.report_id));
    const rawData = await api.xmlRequest('GET', data.aggregationUrls.elements[0].url);
    const { report } = JSON.parse(`{${rawData}}`);                         
  } catch(e) {
    // send notification
  }
}