Express API无法返回fetch获取的数据,请求技术排查
问题:异步函数返回数据异常,Express路由无数据返回
我遇到一个无法解决的问题,代码逻辑看似正确但无法正常运行。以下是我的代码:
const getPhones = async () => { await fetch(url, requestOptions) .then((response) => response.text()) .then((XMLdata) => { const parser = new XMLParser() const jObj = parser.parse(XMLdata) let data = jObj['soapenv:Envelope']['soapenv:Body']['ns:listPhoneResponse']['return']['phone'] console.log(data) return data }) .catch((error) => console.log('error', error)) }
该函数返回的JSON数据可在console.log(data)中查看:
[ { name: 'SEP805E0C47A189', model: 'Third-party SIP Device (Basic)' }, { name: 'SEPDCEB94CE9A65', model: 'Cisco 7821' }, { name: 'TCT-442001', model: 'Cisco Dual Mode for iPhone' }, { name: 'BOT-441015', model: 'Cisco Dual Mode for Android' }, { name: 'SEP70708B219FC8', model: 'Cisco 8851' }, ]
我的Express路由代码如下:
export const phonesData = (req, res) => { res.status(200).json(getPhones) } router.get('/api/phones', phonesData)
当访问localhost:3000/api/phones时,仅得到200响应但无数据返回;若将控制台输出的数据存入常量并返回则正常。getPhones是异步函数,本应等待fetch执行完成后返回解析后的JSON,请问我哪里出错了?
解决方案
你的代码存在三个核心问题,逐一修正即可解决:
1. getPhones函数未返回异步操作结果
async函数内部,你使用了await fetch(...)但没有返回整个Promise链的结果,导致调用getPhones()时,最终得到的是一个resolved为undefined的Promise。
修正后的getPhones函数(保留then链写法):
const getPhones = async () => { // 必须返回fetch的Promise链,让async函数能正确传递结果 return fetch(url, requestOptions) .then((response) => response.text()) .then((XMLdata) => { const parser = new XMLParser() const jObj = parser.parse(XMLdata) const data = jObj['soapenv:Envelope']['soapenv:Body']['ns:listPhoneResponse']['return']['phone'] console.log(data) return data }) .catch((error) => { console.log('error', error) // 抛出错误,让上层路由处理异常 throw error }) }
更推荐的纯async/await写法(避免混用then和await,提升可读性):
const getPhones = async () => { try { const response = await fetch(url, requestOptions) const XMLdata = await response.text() const parser = new XMLParser() const jObj = parser.parse(XMLdata) const data = jObj['soapenv:Envelope']['soapenv:Body']['ns:listPhoneResponse']['return']['phone'] console.log(data) return data } catch (error) { console.log('error', error) throw error } }
2. 路由中未调用getPhones函数
你直接将getPhones函数引用传给了res.json(),而不是调用它获取结果。必须调用getPhones()才能触发异步操作。
3. 路由处理函数未处理异步逻辑
Express路由函数如果要处理异步操作,需要声明为async函数,并用await等待异步函数执行完成,否则会直接返回响应,等异步操作结束时已经无法修改响应内容。
修正后的路由代码:
// 声明为async函数,用await等待getPhones的执行结果 export const phonesData = async (req, res) => { try { const phones = await getPhones() res.status(200).json(phones) } catch (error) { // 捕获异常,返回错误响应 res.status(500).json({ error: '获取设备数据失败' }) } } router.get('/api/phones', phonesData)
内容的提问来源于stack exchange,提问作者user22790531
相关产品推荐
相关产品推荐

