Next.js Google Places API报错:API未返回响应求助
问题
我用Google Maps编写了获取指定坐标附近场所及海滩的代码,在Next.js组件中通过useSWR钩子调用该API接口。所有数据均可正常返回,但在首次执行Axios调用前,控制台出现错误提示:
API resolved without sending a response for /api/google/places/33.807501/-78.70039, this may result in stalled requests.
作为新手无法定位问题所在,希望得到解决建议,相关代码如下:
const axios = require("axios"); const GetNearbyPlaces = async (req, res) => { const { latitude, longitude } = req.query; const radius = 50000; const types = [ "airport", "tourist_attraction", "amusement_park", "aquarium", "art_gallery", "bar", "museum", "night_club", "cafe", "restaurant", "shopping_mall", "store", "spa", ]; function checkFunc(arr, val) { return arr.some(arrVal => val === arrVal); } const url = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${latitude}%2C${longitude}&radius=${radius}&key=${process.env.CW_GOOGLE_MAPS_API_KEY}`; const beachesUrl = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${latitude}%2C${longitude}&radius=${radius}&type=natural_feature&key=${process.env.CW_GOOGLE_MAPS_API_KEY}`; try { let results = []; let beaches = []; const fetchNearbyBeaches = async (urlWithToken = null) => { await axios.get(urlWithToken ? urlWithToken : beachesUrl).then(data => { beaches = [...beaches, ...data.data.results]; if (data?.data?.next_page_token) { const newUrl = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?key=${process.env.CW_GOOGLE_MAPS_API_KEY}&pagetoken=${data.data.next_page_token}`; setTimeout(() => { fetchNearbyBeaches(newUrl); }, 2000); } else { beaches.length > 5 && beaches.splice(5); results.length > 5 && results.splice(5); const finalResults = [...beaches, ...results]; finalResults.length > 10 && finalResults.splice(10); return res.status(200).json({ data: { results: finalResults }, success: true, }); } }); }; const fetchNearbyPlaces = async (urlWithToken = null) => { await axios.get(urlWithToken ? urlWithToken : url).then(data => { results = [...results, ...data.data.results]; if (data?.data?.next_page_token) { const newUrl = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?key=${process.env.CW_GOOGLE_MAPS_API_KEY}&pagetoken=${data.data.next_page_token}`; setTimeout(() => { fetchNearbyPlaces(newUrl); }, 2000); } else { const dirtyResultsWithDuplicates = []; results.map(result => { return types.map(type => { if (checkFunc(result.types, type) && !result.types.includes("lodging")) { dirtyResultsWithDuplicates.push(result); } }); }); const set = new Set(dirtyResultsWithDuplicates); const filtered = Array.from(set); results = filtered.length > 10 ? filtered.splice(10) : filtered; return fetchNearbyBeaches(); } }); }; fetchNearbyPlaces(); } catch (err) { res.status(500).json({ message: err.message, statusCode: 500, }); } }; export default GetNearbyPlaces;
解决建议
问题根源
- API路由函数
GetNearbyPlaces是异步函数,但调用fetchNearbyPlaces()时未加await,导致Next.js误以为路由逻辑已执行完毕,提前结束请求上下文,而实际异步请求还在处理,因此抛出警告。 - 使用
setTimeout嵌套调用异步函数时,没有正确处理Promise链,导致后续响应逻辑脱离当前请求上下文,进一步加剧问题。
修复步骤
- 添加
await等待异步函数执行:调用fetchNearbyPlaces()时加上await,确保Next.js等待所有异步操作完成后再结束路由。 - 替换
setTimeout为Promise延迟函数:把setTimeout改成返回Promise的函数,用await等待延迟后再请求下一页,保证Promise链完整性。 - 统一使用
async/await替代.then():简化代码逻辑,避免回调嵌套导致的上下文丢失。
修改后的代码示例
const axios = require("axios"); // 封装延迟函数,替代setTimeout const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); const GetNearbyPlaces = async (req, res) => { const { latitude, longitude } = req.query; const radius = 50000; const types = [ "airport", "tourist_attraction", "amusement_park", "aquarium", "art_gallery", "bar", "museum", "night_club", "cafe", "restaurant", "shopping_mall", "store", "spa", ]; const checkFunc = (arr, val) => arr.some(arrVal => val === arrVal); const url = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${latitude}%2C${longitude}&radius=${radius}&key=${process.env.CW_GOOGLE_MAPS_API_KEY}`; const beachesUrl = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${latitude}%2C${longitude}&radius=${radius}&type=natural_feature&key=${process.env.CW_GOOGLE_MAPS_API_KEY}`; try { let results = []; let beaches = []; const fetchNearbyBeaches = async (urlWithToken = null) => { // 用await替代.then() const data = await axios.get(urlWithToken ? urlWithToken : beachesUrl); beaches = [...beaches, ...data.data.results]; if (data?.data?.next_page_token) { const newUrl = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?key=${process.env.CW_GOOGLE_MAPS_API_KEY}&pagetoken=${data.data.next_page_token}`; // 用await等待延迟后再递归调用 await delay(2000); await fetchNearbyBeaches(newUrl); } else { // 截取数据 if (beaches.length > 5) beaches.splice(5); if (results.length > 5) results.splice(5); const finalResults = [...beaches, ...results]; if (finalResults.length > 10) finalResults.splice(10); res.status(200).json({ data: { results: finalResults }, success: true, }); } }; const fetchNearbyPlaces = async (urlWithToken = null) => { // 用await替代.then() const data = await axios.get(urlWithToken ? urlWithToken : url); results = [...results, ...data.data.results]; if (data?.data?.next_page_token) { const newUrl = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?key=${process.env.CW_GOOGLE_MAPS_API_KEY}&pagetoken=${data.data.next_page_token}`; // 用await等待延迟后递归 await delay(2000); await fetchNearbyPlaces(newUrl); } else { // 过滤数据 const dirtyResultsWithDuplicates = []; results.forEach(result => { types.forEach(type => { if (checkFunc(result.types, type) && !result.types.includes("lodging")) { dirtyResultsWithDuplicates.push(result); } }); }); const filtered = Array.from(new Set(dirtyResultsWithDuplicates)); results = filtered.length > 10 ? filtered.slice(0, 10) : filtered; // 等待海滩数据获取完成 await fetchNearbyBeaches(); } }; // 等待所有异步操作完成 await fetchNearbyPlaces(); } catch (err) { res.status(500).json({ message: err.message, statusCode: 500, }); } }; export default GetNearbyPlaces;
内容的提问来源于stack exchange,提问作者Agustin G.
相关产品推荐
相关产品推荐

