假设我想在case块的各个switch块中执行不同的promise链,并最终通过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块中的异步函数不会在执行到达resValue之前更新res.end()。我可以将switch后的代码移入promise决议中,如下所示:
         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介导的 promise 都以相同的res.end()结尾?

最佳答案

您可以使用单个变量来保存所需resValue的 promise ,如下所示

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

10-05 20:51
查看更多