Node.js如何正确保存并使用http请求返回的异步数据
问题原因
- 你的
await写了等于白写:Node原生https.get是老的回调风格接口,返回值不是Promise,对它加await不会等内部的请求响应、数据拼接逻辑跑完,代码会直接执行return list,这时候list还是空的,async函数返回的Promise自然是pending状态。 async函数永远返回Promise对象,你直接把getData()的调用结果赋值给potions,拿到的永远是这个Promise壳子,不管等多久,你直接打印这个变量都看不到剥出来的具体数据。
修复方案
首先要把回调风格的https请求包装成真正的Promise,等数据接收、解析完成后再返回结果,调用时通过await或者.then()拿到实际数据,不要用setTimeout瞎等——网络请求耗时不固定,等快了数据没回来,等慢了浪费性能。
修正后的完整代码:
require('dotenv').config(); const https = require('https'); const potionsUrl = process.env.POTIONS_URL; const getData = (url) => { // 手动包装Promise,控制resolve/reject时机 return new Promise((resolve, reject) => { const list = []; https.get(url, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { try { const parsedData = JSON.parse(data); list.push(...parsedData); // 数据全部处理完成后再返回结果 resolve(list); } catch (err) { reject(err); } }); }).on('error', (error) => { reject(error); }); }); }; // CommonJS模块下顶层不能直接用await,用自执行async函数包裹逻辑 (async () => { const potions = await getData(potionsUrl); console.log(potions); // 所有需要用到potions的后续逻辑,都要写在await之后的位置 // Do other stuff with potions })();
简化写法
如果你的Node版本是18及以上,全局自带符合标准的fetchAPI,天生返回Promise,不需要手动包装https,代码可以精简很多:
require('dotenv').config(); const potionsUrl = process.env.POTIONS_URL; const getData = async (url) => { const res = await fetch(url); if (!res.ok) throw new Error(`请求错误,状态码:${res.status}`); return await res.json(); }; (async () => { const potions = await getData(potionsUrl); console.log(potions); // 后续逻辑 })();
内容的提问来源于stack exchange,提问作者Franco Ortega
相关产品推荐
相关产品推荐

