Angular中如何在then访问器作用域外获取存储的接口响应数据
问题本质
你遇到的是JavaScript异步执行顺序问题,then回调会在异步请求完成后才执行,你在then外访问数组时,请求还没返回,回调逻辑还没运行,数组自然是空的,不是数据没有被存储,只是访问时机早于数据赋值时机。
另外原代码还存在两个问题:
- 用普通函数作为
then的回调,this指向会偏离当前组件实例,无法正确给组件属性赋值 - 你代码里的
friendRequests是ngOnInit内的局部变量,方法执行结束后外部本来就无法访问
解决方案
方案1:将数组声明为组件属性,用箭头函数修正this指向
把friendRequests定义为组件的实例属性,同时用箭头函数作为then的回调,保证this指向当前组件实例:
// 组件内先声明属性 friendRequests: FriendRequest[] = []; ngOnInit() { this.friendRequestService.getFriendRequests().then((response) => { response.forEach(element => { this.friendRequests.push(new FriendRequest(element.id, element.receiverId, element.senderId, '')); }); console.log('内部长度', this.friendRequests.length); // 依赖数组数据的后续逻辑都放在这里调用即可 this.doSomethingAfterGetData(); }, (err) => { console.log(err); }); } doSomethingAfterGetData() { // 这里访问的friendRequests已经有完整数据 console.log('外部方法访问长度', this.friendRequests.length); }
如果要在模板中渲染该数组,直接绑定即可,Angular变更检测会在数据更新后自动刷新视图。
方案2:用async/await语法简化异步逻辑
用async/await写法可以让异步代码看起来和同步代码逻辑一致,更易维护:
friendRequests: FriendRequest[] = []; async ngOnInit() { try { const response = await this.friendRequestService.getFriendRequests(); response.forEach(element => { this.friendRequests.push(new FriendRequest(element.id, element.receiverId, element.senderId, '')); }); console.log('获取数据完成', this.friendRequests.length); // 后续逻辑直接写在这里即可 } catch (err) { console.log(err); } }
注意:不要通过
setTimeout延时的方式去访问数组,请求返回时间不固定,延时方案不可靠,所有依赖异步返回数据的逻辑,都应该放在异步回调内部、或者等待异步完成后再触发。
内容的提问来源于stack exchange,提问作者CoderTn
相关产品推荐
相关产品推荐

