动态切换API引用疑问:修改Cookie调用changeApi是否生效?
问题解答:当前实现无法动态切换API引用
首先直接给出结论:不行,你现在的代码没办法在设置/移除Cookie并调用changeApi后,让somepage.js里的api引用自动切换到新的API实例。
为什么会出现这个问题?
我们拆解一下代码的执行逻辑:
- 当
somepage.js导入api时,它拿到的是apicontainer.js中let api = getApi()这句代码创建的初始变量引用——此时api指向mockApi或者realApi中的一个,完全取决于导入时的Cookie值。 - 后续修改Cookie并调用
changeApi()时,这个函数只是在apicontainer.js内部把本地的api变量重新赋值成了新的API对象,但somepage.js里已经导入的api变量,依然指向最开始的那个对象,不会同步更新。
简单来说:模块导出的是变量的快照引用,内部重新赋值不会影响外部已经拿到的引用。
怎么修改才能实现动态切换?
这里有两个实用的可行方案:
方案1:导出获取API的函数,每次使用都拿最新实例
修改apicontainer.js,去掉固定的api变量,直接导出getApi函数:
import mockApi from './mock-api'; import realApi from './api'; export function getApi() { return Cookies.get('isMock') ? mockApi : realApi; }
然后在somepage.js里,每次需要调用API时都执行getApi()获取最新实例:
import { getApi } from './path-to/apicontainer'; // 每次调用API都用最新的实例 getApi().getUserList().then(data => { // 处理数据逻辑 });
这个方案最直接,每次调用都会检查Cookie值,返回对应的API实例。
方案2:用包装对象承载API实例,通过属性访问获取最新值
修改apicontainer.js,把API实例放在一个对象的属性里:
import mockApi from './mock-api'; import realApi from './api'; const apiWrapper = { current: Cookies.get('isMock') ? mockApi : realApi }; export function changeApi() { apiWrapper.current = Cookies.get('isMock') ? mockApi : realApi; } export default apiWrapper;
然后在somepage.js里,通过访问api.current来调用API:
import api from './path-to/apicontainer'; // 调用时用api.current,changeApi后会自动拿到新的实例 api.current.getOrderDetail(id).then(data => { // 处理数据逻辑 });
这个方案保留了changeApi方法,适合需要主动触发切换的场景,外部通过访问对象属性的方式获取最新的API实例。
内容的提问来源于stack exchange,提问作者hashbytes
相关产品推荐
相关产品推荐

