TypeScript传入LogChanges的回调函数调用返回undefined如何解决
问题现象:被调用方法返回undefined
已知错误触发逻辑但未定位到具体修复点,涉及RxJS subscribe 嵌套调用的业务代码如下:
.subscribe(([a, b]: [any, any]) => { if (this.files.length > 0) { const setImagesStatus = (b.body.objectData as DtoSetAppBackgroundImagesStatus); if (setImagesStatus.success) { this.hasBackgroundImages = true; this.files = []; notify('Data successfully updated', 'success'); } else { notify('Application background images upload error. ' + setImagesStatus.info, 'error', 9000); } } else { notify('Data successfully updated', 'success'); } const parsedUserBeforeChanges = new UserPreLogDataConverter(this.groupsService,this.groups).GetPreLogData(updateUserDto); const parsedUserAfterChanges = new UserPreLogDataConverter(this.groupsService,this.groups).GetPreLogData(this.userWithNoChanges); this.eventLogEndpointSvc .addLogs(this.serverEventLogger .LogChanges(JSON.parse(JSON.stringify(parsedUserBeforeChanges)),JSON.parse(JSON.stringify(parsedUserAfterChanges)), () => { this.userCustomLogFunction(parsedUserBeforeChanges,parsedUserAfterChanges); } )).subscribe().add(this.userWithNoChanges=JSON.parse(JSON.stringify(updateUserDto)));} );
this.userCustomLogFunction 方法实现如下:
userCustomLogFunction(userWithNoChanges: UserPreLogData,updateUserDto: UserPreLogData): Array<DtoEventLog> { const oldGroupIds = userWithNoChanges.groups.map(x=>x.id); const newGroupIds = updateUserDto.groups.map(x=>x.id); const addedToGroups = newGroupIds.filter(x => !oldGroupIds.some(y => JSON.stringify(x) === JSON.stringify(y))); const deletedFromGroups = oldGroupIds.filter(x => !newGroupIds.some(y => JSON.stringify(x) === JSON.stringify(y))); const groupLogs: DtoEventLog[] = []; for(const id in addedToGroups) { const evLog = new DtoEventLog(); evLog.methodName = 'LiftaKitMobileAppTestUsers.Update'; evLog.objectId=addedToGroups[id].toString(); evLog.login=this.authService.getUser().login; evLog.firstName =this.authService.getUser().firstName; evLog.lastName = this.authService.getUser().lastName; evLog.email = this.authService.getUser().email; evLog.logType=EventLogType.UPDATE.toString(); evLog.scope=EventLogScope.GROUP.toString(); evLog.input ='Added user' + updateUserDto.firstName + ' ' + updateUserDto.lastName + ' login: ' + updateUserDto.login + ' no: '+ updateUserDto.no +', id: ' + updateUserDto.iD; groupLogs.push(evLog); } for(const id in deletedFromGroups) { const evLog = new DtoEventLog(); evLog.methodName = 'LiftaKitMobileAppTestUsers.Update'; evLog.objectId=deletedFromGroups[id].toString(); evLog.login=this.authService.getUser().login; evLog.firstName =this.authService.getUser().firstName; evLog.lastName = this.authService.getUser().lastName; evLog.email = this.authService.getUser().email; evLog.logType=EventLogType.UPDATE.toString(); evLog.scope=EventLogScope.GROUP.toString(); evLog.input ='Deleted user' + updateUserDto.firstName + ' ' + updateUserDto.lastName + ' login: ' + updateUserDto.login + ' no: '+ updateUserDto.no +', id: ' + updateUserDto.iD; groupLogs.push(evLog); } return groupLogs; }
代码整体运行无其他报错,仅存在异常:在LogChanges方法内部通过logMethod()调用传入的回调方法时,始终返回undefined,初步怀疑第一层subscribe中addLogs和LogChanges的调用写法存在错误。
LogChanges 方法实现如下:
LogChanges<Type>(ob1: Type,ob2: Type=null,logMethod: Function = () => new Array<DtoEventLog>()): Array<DtoEventLog> { const additionalRelation = logMethod(); //rest code here }
问题根因
和RxJS subscribe嵌套写法无关,问题出在传入LogChanges的回调函数本身:
你传入的是带大括号的代码块形式箭头函数() => { 调用方法 },这类箭头函数不会自动返回内部执行结果,没有手动写return的情况下,函数执行完默认返回undefined,所以LogChanges里拿到的返回值永远是undefined。
修复方案
两种改法任选其一即可:
- 显式返回方法执行结果,修改传入的回调函数:
() => { return this.userCustomLogFunction(parsedUserBeforeChanges,parsedUserAfterChanges); }
- 用箭头函数隐式返回写法,去掉大括号,单表达式会自动返回执行结果:
() => this.userCustomLogFunction(parsedUserBeforeChanges,parsedUserAfterChanges)
内容的提问来源于stack exchange,提问作者The Trainer
相关产品推荐
相关产品推荐

