如何用JavaScript保存API获取的数据?解决Promise空写入问题
问题分析与解决方法
核心问题原因
const nutrients = getData().then(...)这行代码里,nutrients并不是你要的营养数据,而是一个未完成的Promise对象。直接对它执行JSON.stringify时,就会得到{}。fs.writeFile是立即执行的,这时候API请求还没完成,自然写入的是未resolved的Promise,不是目标数据。
解决方案1:将文件写入逻辑放在then回调内
确保等API请求完成、拿到实际数据后再执行文件写入:
const fetch = require("node-fetch"); const fs = require('fs'); const params = { api_key: 'i8BGQ3wZNm7Urp1Vb5ly2mfVPcHprcweMGPasvXD', query: 'carrot, raw', dataType: ['Survey (FNDDS)'], pagesize: 1, } const api_url = `https://api.nal.usda.gov/fdc/v1/foods/search?api_key=${encodeURIComponent(params.api_key)}&query=${encodeURIComponent(params.query)}&dataType=${encodeURIComponent(params.dataType)}&pageSize=${encodeURIComponent(params.pagesize)}` function getData() { return fetch(api_url).then(response => response.json()) }; // 把写入操作放到then回调里,确保拿到实际数据后再执行 getData().then(data => { const nutrients = data.foods[0].foodNutrients; // 第三个参数2用于格式化JSON,方便阅读,可选 fs.writeFile('/Users/Mark/Desktop/scrap/output.txt', JSON.stringify(nutrients, null, 2), function(err) { if(err) { return console.log(err); } console.log("The file was saved!"); }); });
解决方案2:使用async/await简化异步逻辑
用async/await让代码更接近同步写法,同时使用Promise版的fs模块避免回调嵌套:
const fetch = require("node-fetch"); const fs = require('fs').promises; // 使用Promise版fs API const params = { api_key: 'i8BGQ3wZNm7Urp1Vb5ly2mfVPcHprcweMGPasvXD', query: 'carrot, raw', dataType: ['Survey (FNDDS)'], pagesize: 1, } const api_url = `https://api.nal.usda.gov/fdc/v1/foods/search?api_key=${encodeURIComponent(params.api_key)}&query=${encodeURIComponent(params.query)}&dataType=${encodeURIComponent(params.dataType)}&pageSize=${encodeURIComponent(params.pagesize)}` async function getData() { const response = await fetch(api_url); return response.json(); }; // 自执行异步函数处理逻辑 (async () => { try { const data = await getData(); const nutrients = data.foods[0].foodNutrients; await fs.writeFile('/Users/Mark/Desktop/scrap/output.txt', JSON.stringify(nutrients, null, 2)); console.log("The file was saved!"); } catch (err) { console.error(err); } })();
内容的提问来源于stack exchange,提问作者Mark Pribylnov
相关产品推荐
相关产品推荐

