如何在没有多个try-catch块和调用多个服务的情况下设置多个属性-Typescript?

如何在没有多个try-catch块和调用多个服务的情况下设置多个属性-Typescript?,typescript,service,properties,try-catch,Typescript,Service,Properties,Try Catch,我正在收集数据以设置属性列表,但是它调用了许多不同的服务来帮助获取这些数据。如果任何服务出现问题,它将抛出一个错误。 如果抛出错误,我希望数据只为该特定属性返回null,并继续获取其余数据 如何在不将每个服务调用包装在try-catch块中的情况下执行此操作 也就是说,这将获取所有属性,但如果任何操作失败,则不会设置之后的属性 public async getAllProperties(){ try { const [studentYear, numOfCourses, numOfSemest

我正在收集数据以设置属性列表,但是它调用了许多不同的服务来帮助获取这些数据。如果任何服务出现问题,它将抛出一个错误。 如果抛出错误,我希望数据只为该特定属性返回null,并继续获取其余数据

如何在不将每个服务调用包装在try-catch块中的情况下执行此操作

也就是说,这将获取所有属性,但如果任何操作失败,则不会设置之后的属性

public async getAllProperties(){
try {
 const [studentYear, numOfCourses, numOfSemesters, startDate, gradDate] = 
await Promise.all([
   studentService.getStudentYear(), 
   courseService.getNumOfCourses(),
   semesterService.getNumOfSemesters(), 
   .... (etc)
])} catch (e){
   console.log("error with getting Properties");
 }
}
例如,如果我调用getAllProperties(),courseService抛出一个错误,我希望numOfCourses为null,并让它继续检查semestService.getNumofCourse并继续设置其余属性

如果没有每个服务的try catch,我怎么能做到这一点?也就是说,我不想为每一处房产写这个

try {
studentService.getStudentYear
} catch (e){
console.log("error in student Year");
studentYear = null;
}

try {
courseService.getNumOfCourses()
} catch (e){
console.log("error in get Num Of courses");
numOfCourses = null;
}


谢谢你的帮助和建议

我建议
承诺。一切都解决了
。此方法返回一个承诺,该承诺在所有给定的承诺都已履行或拒绝后解析,其中包含一个对象数组,每个对象都描述每个承诺的结果

每个承诺必须使用
try-catch
检测错误,如果有错误,则返回
null
。您可以创建一个等待承诺的函数,如果出现错误,则返回结果或null。这样,您只需使用
try catch
一次

下面是一个正在使用的代码示例

函数getAllProperties(){ Promise.allSettled([getName(),getAge()])。然后(data=>{ console.log(数据) }) } 函数getName(){ return returnNullIfFail(()=>newpromise((res,rej)=>res(“某个名字”)) } 函数getAge(){ return returnNullIfFail(()=>newpromise((res,rej)=>rej(“某些错误”)) } 异步函数returnNullIfFail(somePromise:()=>Promise):Promise{ 试一试{ 回报等待承诺 }捕捉(错误){ 返回空 } } getAllProperties()
我喜欢亚历克斯的解决方案。但如果产生的
{status:“fullfilled”,value:2018}
是一个问题,下面是我建议的解决方案:

var obj = {
  getStudentYear: () => new Promise(res => res(2018)),
  getNumOfCourses: () => new Promise(res => res(8)),
  getFailed: () => new Promise( (res, rej) => rej('failed'))
}

async function resolveOrNull(func){
  try{
    let x = await func()
    return x;
  } catch(err) {
    console.log(err);
    return null;
  }
}

async function getAllProperties() {
  return {
    studentYear: await resolveOrNull(obj.getStudentYear),
    numOfCourses: await resolveOrNull(obj.getNumOfCourses),
    getFailed: await resolveOrNull(obj.getFailed)
  }
}

getAllProperties()
  .then(res => console.log(res))
  .catch(err => console.log(err))
编辑:假设您想对代码进行测试。您模拟了该功能,现在需要确保生成的
studentYear
等于
2018
的预期值:

如果使用的是基元值,则可以执行以下操作:

 let studentYear = test.getStudentYear() // returns 2018
 studentYear === 2018 // this is TRUE
如果您正在使用对象:

let studentYear = test.getStudentYear() // returns {status: "fullfilled", value: 2018}
studentYear === {status: "fullfilled", year: 2018} // this is FALSE
当Javascript将一个对象与另一个对象进行比较时,它是通过引用进行比较的,而不是通过值进行比较的。在使用objest/数组时,我遇到了很多其他令人头痛的问题,并尽可能避免使用它。但事实往往并非如此,老实说,这通常是好的,但他们确实倾向于将原本非常简单的事情过于复杂化

编辑2:(这开始变得有点“草率”)

Edit3:(这更像是你应该做的事情,但是有很多不同的方法来处理异步代码带来的问题)


感谢您的快速回复和详细回答!非常感谢。
{status:“fullfilled”,value:2018}
问题从何而来?@Suzy我执行了Alex的回答,看到了
的承诺。allselled
返回的是一个对象,而不是一个直接的值。有时候对象在javascript中可能有点令人头疼,但我不确定在您的情况下是否会出现这种情况。(我将插入一个示例,并进行编辑,以解释对象如何引起头痛)非常感谢Michael!是的,这是一个需要注意的重要问题。有没有办法让res和err以相同的顺序打印出来,而不是分开打印?即)常数[testA,testBFails,testC]。它记录[“a”,失败,“c”]。不要在catch responsedit中记录[“a”、“c”]和[fail]:谢谢,忽略我误解的上述评论。我尝试将结果设置为全局变量,以便在文件的其他地方访问。但它显示的是未定义的。不能在then块中将“res”设置为全局变量吗?
let studentYear = test.getStudentYear() // returns {status: "fullfilled", value: 2018}
studentYear === {status: "fullfilled", year: 2018} // this is FALSE
//... previous code
let globalVariable;

getAllProperties()
  .then((res) => {
    globalVariable = res;
    useGlobal();
  })
  .catch((err) => console.log(err));

function useGlobal() {
  console.log(globalVariable); // This contains the correct obj
  //  anything else that uses the global variable 
  //    should be called inside this function
}

console.log(globalVariable); // This is undefined
getAllProperties()
  .then(useAllProperties)
  .catch((err) => console.log(err));

function useAllProperties = (res) => {
  console.log(res);
  // run code that needs the data
}