async函数执行不符合预期求助:HTTP请求异步执行顺序错误
问题分析与解决方案
嘿,我来帮你搞定这个异步顺序的问题!
为什么会出现这个问题?
你虽然给函数加了async,也用了await,但这里有个关键误区:this.http.get()返回的是RxJS的Observable,而await只会等待Promise完成,对Observable的subscribe回调完全不起作用。
代码的实际执行顺序是这样的:
- 调用
this.http.get()发起异步请求 - 立刻执行
subscribe(),但回调函数要等请求成功后才会触发 - 直接跳到函数末尾的
console.log(this.contacts)执行,这时候请求还没完成,this.contacts还没被赋值 - 请求成功后,才进入
subscribe回调给this.contacts赋值并打印第一个log
这就是为什么第二个log先执行,而且值不符合预期的原因。
两种修复方案
方案1:把Observable转成Promise(推荐和async/await配合)
RxJS提供了firstValueFrom或lastValueFrom(替代已弃用的toPromise),可以把Observable转换成Promise,让await正确等待请求完成:
// 先导入firstValueFrom import { firstValueFrom } from 'rxjs'; async fetchContacts() { // 等待请求完成,拿到响应结果 const res = await firstValueFrom(this.http.get('http://localhost:3000/contacts')); const newContacts = [].concat(res); this.contacts = newContacts; console.log(this.contacts); // 第一个log console.log(this.contacts); // 第二个log,顺序和值都符合预期 }
这样整个函数会等待请求完成后再继续执行,两个log就会按你想要的顺序输出,值也完全一致。
方案2:把后续操作放进subscribe回调里
如果你想保留Observable的订阅模式,直接把第二个console.log移到subscribe的回调函数里就行:
fetchContacts() { this.http.get('http://localhost:3000/contacts') .subscribe(res => { const newContacts = [].concat(res); this.contacts = newContacts; console.log(this.contacts); // 第一个log console.log(this.contacts); // 第二个log,顺序正确 }); }
这种方式下,所有依赖请求结果的代码都在回调内,自然会等到请求成功后再执行,顺序问题就解决了。
内容的提问来源于stack exchange,提问作者Crova
相关产品推荐
相关产品推荐

