使用module.exports导出的request异步请求返回undefined如何修复
问题根因
你遇到的是JS异步回调的典型问题:你使用的request库是回调式异步API,RequestCallback 会在请求完成后才触发执行,而外层 apiCall 是同步执行的,请求发起后函数就直接返回了,此时回调还没运行,自然拿不到返回的 new_body,所以得到的是undefined。
最小改动修复方案
提供两种改动量极小的方案,原有业务逻辑几乎不用重写:
方案1:沿用回调模式(改动最小)
仅需给apiCall增加回调参数,把处理完成的结果传递到外部即可。
第一步修改services.js
function RequestCallback(outerCallback, error, response, body) { if(error) { console.log(error); return outerCallback(error); } var new_body = /* do something with the body */ console.log(new_body); // 把处理后的结果传给外部回调 outerCallback(null, new_body); } var apiCall = function apiCall(payload, authObj, guest, outerCallback) { var reqBody = /* build the body here */ request({ url: 'the api url', method: 'POST', encoding: null, headers: { //pass some headers }, body: reqBody, // 绑定外部回调作为第一个参数传入RequestCallback }, RequestCallback.bind(null, outerCallback)); } module.exports = { apiCall: apiCall };
第二步修改调用文件
const apiService = require("./services.js"); apiService.apiCall(payload, authObj, guest, function(error, res) { if(error) return console.error('请求错误', error); // 此处可正常拿到返回结果,后续所有依赖res的逻辑都放在这个回调内即可 console.log(res); });
方案2:封装为Promise(后续逻辑编写更便捷)
如果想要避免回调嵌套,后续可以用async/await写逻辑,改动量也很小:
第一步修改services.js
function RequestCallback(resolve, reject, error, response, body) { if(error) { console.log(error); return reject(error); } var new_body = /* do something with the body */ console.log(new_body); resolve(new_body); } var apiCall = function apiCall(payload, authObj, guest) { var reqBody = /* build the body here */ // 返回Promise实例 return new Promise((resolve, reject) => { request({ url: 'the api url', method: 'POST', encoding: null, headers: { //pass some headers }, body: reqBody, }, RequestCallback.bind(null, resolve, reject)); }) } module.exports = { apiCall: apiCall };
第二步修改调用文件
可任选.then方式或者async/await方式:
const apiService = require("./services.js"); // 方式1:用.then链式调用 apiService.apiCall(payload, authObj, guest) .then(res => { console.log(res); // 后续逻辑写这里 }) .catch(error => console.error('请求错误', error)); // 方式2:在async函数中用await(代码更简洁) async function yourBusinessFunction() { try { const res = await apiService.apiCall(payload, authObj, guest); console.log(res); // 后续逻辑写这里 } catch (error) { console.error('请求错误', error); } }
内容的提问来源于stack exchange,提问作者Tasos
相关产品推荐
相关产品推荐

