首页 文章

Bluebird Promise Chains:'Catch' with Result

提问于
浏览
6

为了使这个问题对尽可能多的人有用,我将排除我的具体实现细节,除了我正在使用下面的Node Express的Bluebird promise库 .

所以,假设我有以下链(其中 P 返回一个promise, res 是Express HTTP响应对象):

P().then(function(){
    // do nothing if all went well (for now)
    // we only care if there is an error
}).catch(function(error){
    res.status(500).send("An error occurred");
}).then(function(){
    return P();
}).then(function(pVal1){
    return [pVal1, P()];
}) // TODO: catch an error from P() here and log pVal1
.spread(function(pVal1, pVal2){
    if(pVal1 === pVal2) {
        console.log("Success!");
    } else {
        console.log("Failure");
    }
});

我在上面放置 TODO 注释的地方是我想要捕获可能在我调用 P 时出现的错误 . 如果我发现错误,我想记录 pVal1 然后发送500错误,就像在第一次捕获中所做的那样 . 但是,我不确定这是否可能与我如何构建我的链 .

我相信我需要做一些“分支”,但我认为我不能理解这个概念,以阻止JavaScript的异步特性使我最好!因此,任何帮助都是非常感谢 .

2 回答

  • 1

    不要忘记在链的末尾捕捉错误 . 这也是发送回复的地方 .

    在链中间捕获错误是为了间歇性的错误处理;链继续运行,所以暂时不发送回复 .

    这是尝试它的东西:

    // example middleware
    function handle(req, res, next) {
        log("----------------");
        return async("p1", "foo").then(function (pVal1) {
            return pVal1;
        }).then(function (pVal1) {
            var p2a = async("p2a", "bar"),
                p2b = async("p2a", "bar").catch(function (error) {
                    log("Logging: " + error + " (pVal1 " + pVal1 + ")");
                });
            return [p2a, p2b];
        }).spread(function (pVal1, pVal2) {
            if (pVal1 === pVal2) {
                res.send("Success!");
            } else {
                res.send("Failure");
            }
        }).catch(function (error) {
            res.status(500).send("An error occurred");
            log("Logging: " + error);
        });
    }
    
    // ---------------------------------------------------------------------
    // mockup response object
    var res = {
        status: function (code) {
            log("Sending status: " + code);
            return this;
        },
        send: function () {
            log("Sending response: " + [].join.call(arguments, " "));
            return this;
        }
    };
    
    // mockup promise generator
    function async(name, value) {
        return new P(function (resolve, reject) {
            if ( confirm("let " + name + " succeed?") ) {
                log(name + " succeeds...");
                resolve(value);
            } else {
                log(name + " fails...");
                reject(name + " has failed");
            }
        });
    }
    
    function log() {
         var msg = document.createElement("DIV");
         msg.textContent = [].join.call(arguments, " ");
         document.getElementById("log").appendChild(msg)
         document.body.scrollTop = document.body.scrollHeight;
    }
    
    button {
        position: fixed;
        top: 5px;
    }
    
    <script src="http://cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.33/bluebird.min.js"></script>
    
    <button onclick="handle(null, res, null)">Go</button>
    
    <div id="log"></div>
    
  • 2

    如果您使用显式 Promise.all 而不是将数组返回到 .spread ,则可以执行此操作 .

    }).then(function(pVal1){
        // this becomes a `Promise.all` - the aggregation is explicit
        var all = Promise.all([pVal1, P()]);
        all.catch(function(e){  // "branching", we both return and `catch` the promise
            console.log("Error, pVal1 is", pVal1);
        });
        return all; // return it
    }).spread(function(pVal1, pVal2){
           // ....
    });
    

相关问题