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