Node.js中app.get调用异步getpage函数无法获取data字段求助
Express路由异步请求返回data字段缺失问题解决
问题场景
在Express的/all路由中调用自定义的getpage()函数,想要返回包含data、success、status、message的完整JSON响应,但实际返回结果里只有success、status、message三个字段,data始终为空(或undefined)。
原代码如下:
function getpage(url, cks) { const curl = new Curl() const urld = url console.log(urld); curl.setOpt(Curl.option.URL, urld) curl.setOpt(Curl.option.SSL_VERIFYPEER, 0) var gh = curl.setOpt(Curl.option.COOKIEFILE, 'cookies/' + cks) curl.setOpt(Curl.option.FOLLOWLOCATION, true) console.log(gh) curl.on('end', function (statusCode, body, headers) { var result = body; console.log(result); return result; this.close(); }); curl.on('error', function (err, curlErrorCode) { console.error(err); console.error(curlErrorCode); this.close(); }); const hg = curl.perform(); } app.get('/all', (req, res) => { let geturl = req.query.url; let getemail = req.query.email; res.json({ data: getpage(geturl, getemail), success: true, status: 200, message: "Done" }) })
问题原因
getpage()内部使用了node-libcurl的异步回调机制:curl.perform()发起请求后,函数会直接执行完毕并返回undefined(因为没有显式返回值),而请求的结果要等到curl.on('end')事件触发时才会拿到。但res.json()是同步执行的,此时getpage()还没完成请求,自然无法获取到data。
解决方案
把getpage()改造成返回Promise的形式,再用async/await处理异步流程,确保拿到请求结果后再返回响应。
1. 改造getpage函数为Promise风格
function getpage(url, cks) { return new Promise((resolve, reject) => { const curl = new Curl() const urld = url console.log(urld); curl.setOpt(Curl.option.URL, urld) curl.setOpt(Curl.option.SSL_VERIFYPEER, 0) curl.setOpt(Curl.option.COOKIEFILE, 'cookies/' + cks) curl.setOpt(Curl.option.FOLLOWLOCATION, true) curl.on('end', function (statusCode, body, headers) { console.log(body); this.close(); resolve(body); // 将请求结果传递给Promise的resolve }); curl.on('error', function (err, curlErrorCode) { console.error(err); console.error(curlErrorCode); this.close(); reject(err); // 将错误信息传递给Promise的reject }); curl.perform(); }); }
2. 改造路由处理函数使用async/await
app.get('/all', async (req, res) => { try { const geturl = req.query.url; const getemail = req.query.email; // 等待getpage完成异步请求,拿到结果 const data = await getpage(geturl, getemail); res.json({ data: data, success: true, status: 200, message: "Done" }) } catch (err) { // 捕获请求失败的情况,返回错误响应 res.status(500).json({ data: null, success: false, status: 500, message: "请求失败:" + err.message }) } })
这样修改后,/all路由会等待getpage的异步请求完成,拿到返回的body内容后再生成JSON响应,data字段就能正确显示请求结果了。
内容的提问来源于stack exchange,提问作者Vishal Kumar
相关产品推荐
相关产品推荐

