Node.js Express项目中如何改写Loader类以返回异步拉取的数据?
问题核心原因
你调用异步方法getFetchedData时没有等待其执行完成,就直接调用同步的getData,同步代码执行优先级高于异步微任务,导致拿到的还是初始值。
修正方案
1. 调整Loader类实现
新增请求缓存避免重复请求,修正异步方法返回值,添加异常处理:
const axios = require('axios'); class Loader{ constructor(){ // 初始数据 this.data = {data:"some data"} // 缓存正在进行的请求Promise,避免重复发起请求 this.fetchPromise = null } async fetchData(){ // 已有正在执行的请求直接返回,避免重复调用 if (this.fetchPromise) return this.fetchPromise try { this.fetchPromise = axios.get("http://localhost:5000/data") const res = await this.fetchPromise this.data = res.data console.log('data from fetchData', this.data) return this.data } catch (err) { // 请求失败重置缓存,方便后续重试 this.fetchPromise = null throw err } } // 同步方法:直接返回当前已存储的数据,可能是初始值也可能是拉取完成后的值 getData(){ return this.data } // 异步方法:等待数据拉取完成后返回最新数据 async getFetchedData(){ const data = await this.fetchData(); console.log('data from getFetchedData', data) return data } }
2. 正确调用方式
必须等待异步拉取完成后再获取数据,有三种常用调用方式:
// 方式1:async自执行函数(支持顶层await的环境可直接用await) ;(async () => { const testLoader = new Loader(); // 等待异步拉取完成 await testLoader.getFetchedData(); const testVar = testLoader.getData(); console.log("test", testVar) })() // 方式2:then链式调用 const testLoader = new Loader(); testLoader.getFetchedData().then(() => { const testVar = testLoader.getData(); console.log("test", testVar) }) // 方式3:直接使用getFetchedData的返回值,无需额外调用getData const testLoader = new Loader(); testLoader.getFetchedData().then(testVar => { console.log("test", testVar) })
可选扩展:让getData也支持异步返回最新数据
如果你希望调用getData也能自动判断是否需要拉取数据,可修改getData为异步方法:
async getData(){ // 还未拉取过数据则先执行拉取 if (!this.fetchPromise) { await this.fetchData() } return this.data }
修改后可直接调用:
const testLoader = new Loader(); const testVar = await testLoader.getData(); console.log("test", testVar)
最终输出结果:
data from fetchData { data: 'test data after fetching' } data from getFetchedData { data: 'test data after fetching' } test { data: 'test data after fetching' }
内容的提问来源于stack exchange,提问作者barteg
相关产品推荐
相关产品推荐

