如何将Module模块中fetch获取的数据导出到另一个模块?
如何在Controller中使用Module类通过fetch获取的characters数据
首先得说,你当前的Module写法有个小问题:在constructor里直接发起的fetch是异步操作,当你在Controller里实例化Module时,this.characters大概率还没被赋值,而且没有可靠的方式等待数据加载完成。咱们得调整Module的结构,让Controller能安全拿到异步加载好的数据。
下面给你几种实用的解决方案:
方案一:把数据逻辑抽成异步方法,用await等待加载完成
这是最符合现代JS最佳实践的方式,结构清晰易维护。
先修改module.js,把fetch逻辑从constructor移到单独的异步方法里:
export class Module { constructor() { // 先初始化空数组,避免后续访问报错 this.characters = []; } // 异步方法:专门负责获取角色数据 async fetchCharacters() { const fetchParams = { method: "GET", mode: "cors", cache: "default" }; const url = 'https://swapi.co/api/people/'; try { const res = await fetch(url, fetchParams); if (!res.ok) { throw new Error(res.statusText); } const data = await res.json(); this.characters = data.results; // 可以直接返回数据,方便外部直接使用 return this.characters; } catch (error) { console.error('获取角色数据失败:', error); throw error; // 把错误抛出去,让调用方处理 } } }
然后在controller.js里,通过await等待数据加载完成:
import { Module } from "./module"; class Controller { constructor() { this.module = new Module(); // 把异步逻辑放到单独的init方法里 this.init(); } async init() { try { // 等待数据加载完成 const characters = await this.module.fetchCharacters(); // 这里就可以正常使用数据了 console.log('拿到的角色列表:', characters); // 也可以直接访问module实例上的characters属性 console.log('也能这样拿:', this.module.characters); } catch (error) { // 统一处理错误 console.error('Controller初始化失败:', error); } } } // 实例化Controller const controller = new Controller();
方案二:用静态方法创建带数据的Module实例
如果你希望Module实例化时自动加载数据,并且让Controller等待这个过程,可以用静态方法封装实例创建逻辑:
修改module.js:
export class Module { constructor() { this.characters = []; } // 静态方法:创建实例并自动加载数据 static async create() { const module = new Module(); await module.fetchCharacters(); return module; } async fetchCharacters() { // 和方案一的fetchCharacters方法完全一样 const fetchParams = { method: "GET", mode: "cors", cache: "default" }; const url = 'https://swapi.co/api/people/'; try { const res = await fetch(url, fetchParams); if (!res.ok) { throw new Error(res.statusText); } const data = await res.json(); this.characters = data.results; } catch (error) { console.error('获取数据失败:', error); throw error; } } }
Controller里这样用:
import { Module } from "./module"; class Controller { constructor() { this.init(); } async init() { try { // 等待Module实例创建并加载完成数据 this.module = await Module.create(); console.log('数据加载完成:', this.module.characters); } catch (error) { console.error('初始化失败:', error); } } } const controller = new Controller();
方案三:回调/自定义事件(兼容旧环境)
如果你的环境不支持async/await,也可以用回调或自定义事件来通知数据加载状态:
回调版本(module.js)
export class Module { constructor() { this.characters = []; } fetchCharacters(callback) { const fetchParams = { method: "GET", mode: "cors", cache: "default" }; const url = 'https://swapi.co/api/people/'; fetch(url, fetchParams) .then(res => { if (!res.ok) { throw new Error(res.statusText); } return res.json(); }) .then(data => { this.characters = data.results; callback(null, this.characters); // 成功时传递数据 }) .catch(error => { console.error('获取数据失败:', error); callback(error); // 失败时传递错误 }); } }
Controller里使用回调:
import { Module } from "./module"; class Controller { constructor() { this.module = new Module(); this.module.fetchCharacters((error, characters) => { if (error) { console.error('加载失败:', error); return; } console.log('拿到数据:', characters); }); } } const controller = new Controller();
个人最推荐方案一,它的代码结构清晰,async/await的异步处理方式也更符合现代JS的阅读习惯,后续维护起来也更方便。
内容的提问来源于stack exchange,提问作者Aleksander
相关产品推荐
相关产品推荐

