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@JaromandaXOP使用箭头函数,非常安全:p
-async
和wait
是ES2017,箭头函数是ES2015。这不是一个非常安全的赌注。@vdegenneresValue=(等待someObj.action_a()).id代码>将反映问题的意图。目前,您正在分配result
而不是result.id
@PatrickRoberts-没有多少人会使用一个有一个而没有另一个的环境-尽管有一些人会使用特别旧的nodej,所以我想这是一个公平的观点将这段代码视为同步的-处理异步代码的危险方式-不使用其他代码而使用async Wait如何:p这就是为什么复制/粘贴是一件坏事:pI不遵循您的指控@vdegenne-当然,我复制/粘贴并更改了OP的代码