Node.js导入模块后无法调用export导出的fetchOptical方法如何解决
问题原因
你遇到的问题由三个错误共同导致:
module.exports重复赋值:settings.js末尾两次定义module.exports,后定义的module.exports = env直接覆盖了前面包含fetchOptical方法的导出对象,你require导入的config本质是env对象,根本不存在fetchOptical属性,自然无法调用。- 方法未执行:即使导出逻辑正确,你业务代码中写的
config.fetchOptical;仅为方法引用,没有添加()触发执行,方法不会自动运行。 - 异步逻辑未等待:
fetchOptical内部是异步axios请求,就算正常调用,你没有等待请求执行完成就读取API_URL,也会拿到未更新的旧值。
修复方案
第一步:修改settings.js导出逻辑
保留一份导出对象,同时包含env数据和fetchOptical方法,且让fetchOptical返回Promise方便外部等待异步执行完成:
const axios = require('axios'); let protocol = ''; let opticalIp = ''; let env = { API_URL: '', configHeaders: '' }; // 初始化请求可以保留 axios.get(`https://IP:9201/api/v1.0/settings/custom-form/Optical`).then(function(response) { if(response.data && response.data.data) { protocol = response.data.data['scheme']; opticalIp = response.data.data['optical_ip']; env.API_URL = `${protocol}://${opticalIp}/`; console.log('dataenv', env); } }).catch(function(error) { console.log('error', error); }); // 合并导出,不要分开写两次module.exports module.exports = { env, fetchOptical: () => { console.log('fetch optical'); // return axios的Promise实例,外部可以await等待 return axios.get(`https://IP:9201/api/v1.0/settings/custom-form/Optical`).then(function(response) { if(response.data && response.data.data) { protocol = response.data.data['scheme']; opticalIp = response.data.data['optical_ip']; env.API_URL = `${protocol}://${opticalIp}/`; console.log('fetch', env); } }).catch(function(error) { console.log('error', error); }); } }
第二步:修改业务代码调用逻辑
调整引入方式,调用fetchOptical时加括号,且用await等待异步执行完成后再读取API_URL:
// 引入整个导出对象 const settings = require('../../config/settings'); getDiscoveryRoutes = async(req, res, next) => { try { if (!req.headers.authorization || !req.headers.authorization.includes("Bearer ")) { responseObj = { status: 'Error', msg: 'Please add token to headers', body: {} }; res.send(responseObj); } else { // 加()调用方法,await等待异步请求完成 await settings.fetchOptical(); const config = settings.env; let token = req.headers.authorization; let configHeaders = { headers: { 'Authorization': token } } console.log('discovery', config.API_URL); try { // 后续axios请求也改成await写法,避免回调嵌套 const response = await axios.get(`${config.API_URL}endpoints/optical/routes/discovered`, configHeaders) responseObj = { status: 'success', msg: 'Record fetched successfully', body: response.data }; res.send(responseObj); } catch (error) { responseObj = { status: 'Error', msg: 'Error occured.', body: error.response?.data?.['service-response']?.['payload']?.['message'] || 'Operation not found' }; res.status(error.response?.status || 500).send(responseObj); } } } catch (error) { console.log('Error::', error); res.status(500).send({status: 'Error', msg: 'Server error', body: {}}) } }
内容的提问来源于stack exchange,提问作者subhra_user
相关产品推荐
相关产品推荐

