调用web服务后forEach未完成就读取userName为undefined如何解决
问题原因
首先明确:Array.forEach 本身是同步遍历方法,会阻塞后续同作用域代码直到遍历完成。你遇到的读取到undefined的核心原因是 你把selectionUser.push的代码写在了subscribe异步回调的外部:getDemandesEnCours是异步web service请求,subscribe的回调函数只会在接口返回数据后才会触发,写在回调外部的push代码不会等待接口返回,会提前执行,此时还没走遍历赋值逻辑,userName自然是undefined。
解决方案
方案1:将push逻辑移到回调内部,遍历完成后执行
把赋值、push逻辑都放在subscribe回调里,遍历结束后加非空判断再执行push,代码示例如下:
this.ws_demandes_en_cours.getDemandesEnCours().subscribe( (ws_data: IAPIListeDemandes) => { this.isLoading = false; this.userId = this.user_info.getUserID(); // 先重置userName避免上次缓存的值影响 this.userName = ''; ws_data.listePasseoDemandesEnCours.forEach(item => { if (this.userId === item.demandeur) { this.userName = item.demandeur_nomPrenom; console.log(this.userName +' test username'); } }); // 遍历完成后,非空判断再push if (this.userName) { this.selectionUser.push(this.userName); console.log(this.userName +' test push user in selectionUserArray') } } )
方案2:更简洁的匹配写法(推荐)
不需要手动遍历,直接用Array.find匹配对应项,性能更高逻辑更清晰:
this.ws_demandes_en_cours.getDemandesEnCours().subscribe( (ws_data: IAPIListeDemandes) => { this.isLoading = false; this.userId = this.user_info.getUserID(); // 直接查找匹配的用户项 const matchedUser = ws_data.listePasseoDemandesEnCours.find(item => item.demandeur === this.userId); if (matchedUser) { this.userName = matchedUser.demandeur_nomPrenom; this.selectionUser.push(this.userName); console.log(this.userName + ' 匹配成功已存入数组') } } )
特殊场景说明
如果你的业务中存在同一个userId对应多个匹配项的情况,需要把所有匹配的用户名都存入数组,可以直接在遍历的判断逻辑中执行push,不需要等待遍历结束:
ws_data.listePasseoDemandesEnCours.forEach(item => { if (this.userId === item.demandeur) { const userName = item.demandeur_nomPrenom; this.selectionUser.push(userName); } });
内容的提问来源于stack exchange,提问作者Shirley
相关产品推荐
相关产品推荐

