首页 > 解决方案 > 如何在 switch 块的每种情况下解决不同的承诺并将它们的结果传递给相同的函数?

问题描述

假设我想在case一个区块的各个区块中执行不同的promise链switch,并最终通过 将结果返回给客户端res.end(),像这样:

app.post('/endpoint',function(req,res){
    var reqValue=req.body.value;
    var resValue="initial value";
    switch(reqValue){
         case 'a':
             someObj.action_a()
             .then(result=>{
                 resValue=result.id;
             });
             break;
         case 'b':
             someObj.action_b()
             .then(result=>{
                 resValue=result.id;
             });
             break;
         default:
             resValue="default";
    }
    doSomethingElse();
    res.end(resValue);
});

最终发生的resValue是返回为"initial value",这是有道理的,因为块中的异步函数在执行到达之前case没有更新。我可以将邮政编码移动到这样的承诺解决方案中:resValueres.end()switch

         case 'a':
             someObj.action_a()
             .then(result=>{
                 resValue=result.id;
                 doSomethingElse();
                 res.end(resValue);
             });
             break;
         case 'b':
             someObj.action_b()
             .then(result=>{
                 resValue=result.id;
                 doSomethingElse();
                 res.end(resValue);
             });
             break;
         default:
             resValue="default";
             doSomethingElse();
             res.end(resValue);

但这是重复代码,因此维护起来更具挑战性。有没有更好的方法让这些以中介为switch中介的承诺都以相同的方式结束res.end()

标签: javascriptnode.jspromise

解决方案


您可以使用单个变量来保持所需 resValue 的承诺,就像这样

app.post('/endpoint',function(req,res){
    let reqValue=req.body.value;
    let p;
    switch(reqValue){
         case 'a':
             p = someObj.action_a().then(result => result.id);
             break;
         case 'b':
             p = someObj.action_b().then(result => result.id);
             break;
         default:
             // p has to be a promise, so make it one
             p = Promise.resolve("default");
    }
    p.then(resValue => {
        doSomethingElse();
        res.end(resValue);
    });
});

或使用现代 javascript,使用 async/await

app.post('/endpoint',async function(req,res){
    let reqValue=req.body.value;
    let resValue="initial value";
    switch(reqValue){
         case 'a':
             resValue = await someObj.action_a().then(result => result.id);
             break;
         case 'b':
             resValue = await someObj.action_b().then(result => result.id);
             break;
         default:
             resValue = "default";
    }
    doSomethingElse();
    res.end(resValue);
});

推荐阅读