如果在 Bluebird 中失败,则处理成功的 HTTP 承诺

Handle successful HTTP promise if one fails in Bluebird

我对 Promises 还很陌生,一直在尝试让这段代码正常工作。这是我的。

var Promise = require('bluebird');

    Promise.join(getProducts, getPricing, function(products, pricing) {
            console.log('products: ' + products.body);
            console.log('pricing: ' + pricing.body);

            // Add pricing to products here

            res.send(products.body);
        })
        .catch(function(e) {
            console.log(e);
            res.sendStatus(500);
        });

要求...

如果两个 API 调用都成功,我的代码似乎可以工作,但如果失败并忽略任何成功的调用,我的代码将始终进入捕获状态。

如果我使用同步 Promise 链,我可以使它正常工作,但我想同时调用两个 API。

如何异步调用两个 API 并在 catch 之外处理结果?

预警:我对承诺很体面,但不是这个特定的图书馆。

var Promise = require('bluebird');

var pricing = getPricing().catch(function(e) {
  return null;
})

Promise.join(getProducts, pricing, function(products, pricing) {
        console.log('products: ' + products.body);
        console.log('pricing: ' + pricing ? pricing.body : '<null>');

        // Add pricing to products here

        res.send(products.body);
}).catch(function(e) {
  console.log(e);
  res.sendStatus(500);
});

您需要将 catch 准确地放在您要处理其失败的承诺上 - 即 getPricing.

Promise.join(getProducts, getPricing.catch(function(err) {
    // ignore or log?
    return null;
}, function(products, pricing) {

    console.log('products: ' + products.body);
    if (pricing) {
        console.log('pricing: ' + pricing.body);
        // Add pricing to products here
    } // else?
    res.send(products.body);
}).catch(function(e) {
    console.log(e);
    res.sendStatus(500);
});

如果您想更明确地区分这两种情况,您也可以使用 getPricing<a href="http://bluebirdjs.com/docs/api/reflect.html" rel="nofollow">.reflect()</a>

修改 getPricing() 使其永远不会失败。最简单的方法是添加顶级 .catch()。下面的示例代码包装了 getPricing() 方法

var Promise = require('bluebird');

function getProducts(){/* add implementation */};

function originalGetPricing(){/* add implementation */};

function getPricing(){
   return originalGetPricing()
     .catch(function(err) {
       return Promise.resolve(/* replace this comment with empty object or some other suitable response */);
     });
};

Promise.join(getProducts, getPricing, function(products, pricing) {
        console.log('products: ' + products.body);
        console.log('pricing: ' + pricing.body);

        // Add pricing to products here

        res.send(products.body);
    })
    .catch(function(e) {
        console.log(e);
        res.sendStatus(500);
    });