Ajax与Express中等待数据库返回数据失败问题排查
嘿,我来帮你拆解下这个问题!你遇到的情况是:调用异步函数后,Promise一直处于pending状态,但控制台能看到数据,前端却拿不到正确结果。咱先理清楚哪里错了,以及你对异步函数的理解误区。
一、你代码里的核心错误
没有在异步环境中等待Promise完成
你在app.post的回调函数里直接调用leagueFixtures(league_name),但这个函数是async的,调用后返回的是一个Promise。之前你尝试用await但报错,是因为外层的回调函数不是async的——await只能在async标记的函数里使用,普通同步函数里用它肯定会语法报错。直接把Pending状态的Promise返回给前端
你把const fixtures = leagueFixtures(league_name)的结果直接传给res.json,但此时fixtures是一个还没完成的Promise,不是实际的查询数据。所以前端拿到的不是你期望的fixture数据,而是一个未resolved的Promise对象。
二、你的理解误区
- 异步函数的返回值特性:所有被
async标记的函数,不管内部return什么值,最终都会被自动包装成一个Promise。所以你不能像同步函数那样直接赋值获取结果,必须用await或者.then()来等待它完成,拿到实际的返回值。 await的使用场景限制:await必须在async函数内部使用,不能在普通的同步回调里直接用。要想在app.post的回调里用await,必须先把这个回调函数标记为async。
三、修正后的代码
index.js 修正版
async function leagueFixtures(league_name){ var data = await queries.league_fixtures(league_name); return data; } // 把回调函数标记为async,这样就能用await了 app.post('/league_fixtures', async function (req, res) { var league_name = req.body.league_name; // 用await等待Promise完成,拿到实际数据 const fixtures = await leagueFixtures(league_name); console.log(fixtures); // 这里打印的就是真实的查询数据了 res.json({success: true, data: fixtures }) });
为什么之前控制台能看到数据?
大概率是queries.league_fixtures函数内部自己做了console.log操作,所以你能在控制台看到数据,但这不代表leagueFixtures函数已经正确把数据返回并resolved了Promise——你只是没在外部等待这个Promise完成,就把它传给了响应。
另外,还要确认queries.league_fixtures确实是返回一个Promise的(如果它是基于回调的函数,你可能需要先把它包装成Promise),不过从你用await调用它来看,应该是已经处理成Promise了。
内容的提问来源于stack exchange,提问作者Richlewis

