Javascript 组合两个服务调用并返回值

Javascript 组合两个服务调用并返回值,javascript,Javascript,你好,我想合并两个电话。然后把它还给我。但是如果两个都失败了,我应该抓住它,如果两个调用中的任何一个都失败了,那没关系,我可以只返回一个有效的调用 这就是我试过的 这两个电话我都有。如何实现承诺,好吗 router.get('/services', (req, res) => { let arr = []; const call1 = service1() .then(res => arr.push({ res, type: 'service1'}

你好,我想合并两个电话。然后把它还给我。但是如果两个都失败了,我应该抓住它,如果两个调用中的任何一个都失败了,那没关系,我可以只返回一个有效的调用

这就是我试过的

这两个电话我都有。如何实现承诺,好吗

router.get('/services', (req, res) => {

    let arr = [];

    const call1 = service1()
        .then(res => arr.push({ res, type: 'service1'} ))
        .catch(error => res.status(error.status).json(error));

    const call2 = service2()
        .then(res => arr.push({ res, type: 'service2'} ))
        .catch(error => res.status(error.status).json(error));
})

Promise.all([service1, service2]).then(values => { 
  // not sure what to do here
});

节点版本:v8.11.1

调用
。服务调用上的catch
将确保传递给
的回调。然后
中的
将始终调用所有()
,因此您需要自己处理错误:

async function callService(fn, type) {
  return service1().then(res => ({ res, type })).catch(err => ({ err }));
}

router.get('/services', (req, res) => {
  const calls = [callService(service1, 'service1'), callService(service2, 'service2')];
  return Promise.all(calls).then(arr => {
    if (arr.every(call => call.err)) {
      // Both elements in arr are errors, handle here
      return;
    }

    // At least 1 was not an error, handle here
  });

在服务调用中调用
.catch
将确保传递给
的回调。然后
Promise中的
将始终调用all()
,因此您需要自己处理错误:

async function callService(fn, type) {
  return service1().then(res => ({ res, type })).catch(err => ({ err }));
}

router.get('/services', (req, res) => {
  const calls = [callService(service1, 'service1'), callService(service2, 'service2')];
  return Promise.all(calls).then(arr => {
    if (arr.every(call => call.err)) {
      // Both elements in arr are errors, handle here
      return;
    }

    // At least 1 was not an error, handle here
  });

Promise.all
如果
Promise
失败,很遗憾会返回一个错误,因此它无法按您希望的方式工作

假设您使用的是
Node.js
8或更高版本,则可以使用
async/wait
进行两次异步调用,并检查其中一次是否返回错误:

router.get(`/services`,(req,res)=>{
//这只是一个简单的检查,但给你一个想法
常量isError=(arg)=>{
返回arg instanceof Error
}
异步函数processRequest(){
常数arr=[]
const call1=await service1().catch(错误=>error)
const call2=await service2().catch(错误=>error)
如果(!isError(调用1)){
arr.push({res:call1,类型:`service1`})
}
如果(!isError(调用2)){
arr.push({res:call2,类型:`service2`})
}
if(isError(计算1)和isError(计算2)){
res.status(call1.status).json(call1)
返回
}
res.status(200).json(arr)
}
processRequest()
})

或者,如果您使用的是
节点
12.10或更高版本,则可以使用
Promise.allSettled
,这将为您提供所需的一切

方法返回一个承诺,该承诺在所有给定承诺都已解析或拒绝后解析,其中包含一个对象数组,每个对象描述每个承诺的结果

将其应用到您的案例中,如下所示:

router.get(`/services`,(req,res)=>{
答应我,一切都解决了([
service1(),
服务2()
])
。然后(结果=>{
const arr=结果
.filter(result=>result.status==`completed`)
.map(结果=>result.value)
如果(arr.length==0){
const{reason}=results.find(result=>result.status===`rejected`)
res.status(reason.status).json(reason)
返回
}
res.status(200).json(arr)
})
.catch(错误=>{
//适当处理其他错误
res.status(500).json(…)
})
})

承诺。如果
承诺失败,所有
都将不幸返回错误,因此它将无法按您希望的方式工作

假设您使用的是
Node.js
8或更高版本,则可以使用
async/wait
进行两次异步调用,并检查其中一次是否返回错误:

router.get(`/services`,(req,res)=>{
//这只是一个简单的检查,但给你一个想法
常量isError=(arg)=>{
返回arg instanceof Error
}
异步函数processRequest(){
常数arr=[]
const call1=await service1().catch(错误=>error)
const call2=await service2().catch(错误=>error)
如果(!isError(调用1)){
arr.push({res:call1,类型:`service1`})
}
如果(!isError(调用2)){
arr.push({res:call2,类型:`service2`})
}
if(isError(计算1)和isError(计算2)){
res.status(call1.status).json(call1)
返回
}
res.status(200).json(arr)
}
processRequest()
})

或者,如果您使用的是
节点
12.10或更高版本,则可以使用
Promise.allSettled
,这将为您提供所需的一切

方法返回一个承诺,该承诺在所有给定承诺都已解析或拒绝后解析,其中包含一个对象数组,每个对象描述每个承诺的结果

将其应用到您的案例中,如下所示:

router.get(`/services`,(req,res)=>{
答应我,一切都解决了([
service1(),
服务2()
])
。然后(结果=>{
const arr=结果
.filter(result=>result.status==`completed`)
.map(结果=>result.value)
如果(arr.length==0){
const{reason}=results.find(result=>result.status===`rejected`)
res.status(reason.status).json(reason)
返回
}
res.status(200).json(arr)
})
.catch(错误=>{
//适当处理其他错误
res.status(500).json(…)
})
})

您使用的是哪个版本的
节点
?v8.11.1谢谢!您是否仍有问题?您使用的是哪个版本的
节点
?v8.11.1谢谢!您仍然有问题吗?您在解释中提到了
async
/
wait
,但在调用
service1
service2
时没有使用它。应该是这样的:
const call1=await service1().catch(error=>error)
您在解释中提到了
async
/
await
,但在调用
service1
service2
时没有使用它。相反,应该是这样的:
const call1=await service1().catch(error=>error)
的返回值。catch
用于代替
的返回值。然后,当您的承诺抛出错误时,
。这允许继续链接承诺-否则,您的
承诺。所有
都必须处理错误。使用
.catch
的返回值,而不是
的返回值。然后,当您的承诺抛出错误时,
。这允许继续链接承诺-否则,您的
承诺。所有
都必须处理错误。