Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在开关块的每种情况下解析不同的承诺,并将其结果传递给相同的函数?_Javascript_Node.js_Promise - Fatal编程技术网

Javascript 如何在开关块的每种情况下解析不同的承诺,并将其结果传递给相同的函数?

Javascript 如何在开关块的每种情况下解析不同的承诺,并将其结果传递给相同的函数?,javascript,node.js,promise,Javascript,Node.js,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() .th

假设我想在
开关
块的不同
案例
块中执行不同的承诺链,并最终通过
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);
});
         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);
最后发生的是
resValue
作为
的“初始值”
返回,这是有意义的,因为
案例中的异步函数在执行到达
res.end()
之前不会更新
resValue
。我可以将post-
开关
代码移动到如下所示的承诺解决方案中:

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

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

您可以使用单个变量来保持所需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);
});

Promise.all
是跟踪所有子promises任务的非常方便的工具

const jobqque=[];
开关(…){
案例:“…”:{
jobque.push(
子费用()
);
}
案例:“…”:{
jobque.push(
次级方案2()
);
}
默认值:{
jobque.push(
defaultOpPromise();
);
}
}
承诺。全部(工作质量)
。然后(结果=>{
...
})

.catch(error=>console.error(error))如果您可以使用JavaScript的新功能,我建议您使用
async
wait
,因为它们易于阅读和使用,您的代码将更改为:

let resValue = "default";
switch (reqValue) {
  case 'a':
    resValue = (await someObj.action_a()).id;
    break;
  case 'b':
    resValue = (await someObj.action_b()).id;
    break;
  default:
    break;
}
doSomethingElse();
res.end(resValue);

或者,您可以创建一个通用函数,根据给定的操作类型返回数据,并在那里设置
开关
,在主函数中使用一个简单的async/await来等待

//切换动作的组合函数
//基于类型(在本例中,计时器位于
//设置超时)
函数doAction(类型){
让时间;
开关(类型){
案例“a”:时间=1000;中断;
案例“b”:时间=2000;中断;
案例c:时间=300;中断;
}
返回新承诺(解决=>{
setTimeout(()=>resolve({id:`${type}1`}),time);
});
}
异步函数主(类型){
试一试{
//将类型传递给doAction函数,
//让他们决定做什么,等待承诺
//解决
const result=等待动作(类型);
//然后只需console.log或res.send结果
const resValue=result.id;
console.log(resValue);
}捕获(e){
控制台日志(e);
}
}
主要(‘b’);
主要(‘a’);

主(“c”)
如果您不能使用
异步/等待
,而必须坚持
承诺
,这里有一个选项(但是,如果您有很多案例,嵌套的ternaries可能会变得难看;请继续阅读,了解不同的想法):

相反,假设您将操作存储在
对象中

const actions = {
  a: () => someObj.action_a();
  b: () => someObj.action_b();
  // ...
  n: () => someObj.action_n();
};

app.post('endpoint', function(req, res) {
  const action = actions[req.body.value];
  (action && action().then(({id}) => id) || Promise.resolve('default'))
    .then(resValue => {
      doSomethingElse();
      res.end(resValue);
    });
});

当只能有一个承诺时,没有理由有一个承诺数组:pyou不能像那样使用
wait
——也就是说,您忘记了显示封闭函数需要是
async
:p
如果您可以使用JavaScript的新功能
-OP使用箭头函数,非常安全:p@JaromandaX故意省略!因为如果他要使用JS的这种现代语法,他肯定会遇到其他问题,需要向自己学习。不用说,我只是想引导他找到一个他可能感兴趣的解决方案:p@JaromandaX
OP使用箭头函数,非常安全:p
-
async
wait
是ES2017,箭头函数是ES2015。这不是一个非常安全的赌注。@vdegenne
resValue=(等待someObj.action_a()).id将反映问题的意图。目前,您正在分配
result
而不是
result.id
@PatrickRoberts-没有多少人会使用一个有一个而没有另一个的环境-尽管有一些人会使用特别旧的nodej,所以我想这是一个公平的观点
将这段代码视为同步的
-处理异步代码的危险方式-不使用其他代码而使用async Wait如何:p这就是为什么复制/粘贴是一件坏事:pI不遵循您的指控@vdegenne-当然,我复制/粘贴并更改了OP的代码