2017-05-24 167 views
0

我希望能够拒绝整个承诺链,如果承诺的任何人以干净的方式失败。我想“捕捉”这种拒绝并发送错误通知。我已经执行了下面的代码:如何拒绝承诺内的承诺

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控制台作为未被捕获的错误。为什么即使我发现它也会冒泡?

+0

我错了,或者你不是已经通过返回Promise.reject()来做这件事吗?我认为你可以简单地放弃一些错误捕捉器,它会全部转到最后一个... –

+1

主要问题似乎是你实际上没有链。你有几个单独的承诺,彼此完全没有关系。你是否打算将所有代码链接在一个承诺链中?现在你的问题不能回答,因为你显然已经知道如何从'.then()'内部拒绝,因为你已经在多个地方做了这个。但是,你必须将所有的承诺都与'Promise.all()'一起收集起来,否则你必须将它们链接在一起。我们不知道您打算如何使用代码。 – jfriend00

+0

好的。我修改了我的问题。希望现在更清楚。基本上我想让我的代码更清洁。顺便说一句,我有承诺链接在一起。例如,aggregateReport对于aggregateData是“then”,individualReport对于aggregateData也是“then”。所以,这些链接在一起。 –

回答

0

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

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

如果这是你想要的并不完全符合,看看蓝鸟 - 功能齐全的承诺库。 Here

UPDATE:如果你想抛弃全部承诺,如果任何函数内部的承诺失败,请尝试实施:

throw validationError; 

希望工程。

+0

OP没有指定他们使用蓝鸟。 – nem035

+0

是的,我发送它以防万一,如果决定。虽然,第一个链接是ES6相关的承诺。 – oneturkmen

+2

然后,您可能想明确说明这一点。只是说一个链接“使用此”并不是非常有用:) – nem035

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 
    } 
}