Node.js调用restcountries API获取数据导出CSV出现空值如何解决
问题修复方案
核心问题根源
- 异步执行时序问题:CommonJS的
require是同步加载逻辑,你在第一个文件中发起的异步接口请求还未返回结果时,第二个文件已经同步拿到了初始值为空的list变量直接用于CSV转换,自然会得到空值。 - 数据结构错误:
Promise.all的回调参数data本身就是所有接口返回结果组成的数组,你执行list.push(data)会把整个结果数组作为单个元素塞入list,最终list的结构是[[...接口返回数据]],不符合json-2-csv库要求的一维对象数组格式,也会导致转换异常。 - 错误处理遗漏:如果某个国家名称查询失败,
catch仅打印错误没有返回兜底值,会导致Promise.all的结果中出现undefined,最终CSV出现空值。 - 接口返回兼容问题:
restcountries的名称查询接口可能返回多个匹配国家,未做处理的话会把数组嵌套进结果,同样会导致转换异常。
修复代码
第一个文件(countryCleaning.js)
需要先安装node环境可用的fetch依赖:npm i node-fetch@2(v2版本支持CommonJS规范引入)
const fetch = require('node-fetch'); // 替换为你自己的国家数组 const currentCountries = ['中国', '美国', '日本']; // 导出异步函数,返回处理完成的国家数据 module.exports = async function getCountryData() { const list = await Promise.all(currentCountries.map(async (country) => { try { // 中文国家名需要编码后再传入接口 const response = await fetch(`https://restcountries.eu/rest/v2/name/${encodeURIComponent(country)}`); const resList = await response.json(); // 取第一个匹配的国家结果,可按需筛选需要的字段 return resList?.[0] || { name: country, error: '无匹配国家数据' }; } catch (err) { console.log(`${country}查询失败:`, err); // 兜底返回错误信息,避免数组出现空值 return { name: country, error: err.message }; } })); // 此处打印即可拿到完整填充后的list数据 console.log('抓取完成的国家数据:', list); return list; }
第二个文件(CSV转换文件)
const fs = require('fs') const converter = require('json-2-csv') // 引入第一个文件导出的异步函数 const getCountryData = require('./countryCleaning') // 等待数据抓取完成后再执行CSV转换 getCountryData().then(list => { converter.json2csv(list, (err, csv) => { if (err) throw err; fs.writeFile('cleanedCountryCodes.csv', csv, 'utf8', function(err){ if(err){ console.log("FS Error:", err) } else { console.log("everything has worked") } }) }) }).catch(err => console.log('处理失败:', err))
查看第一个文件list变量的方法
- 把
console.log(list)放在Promise.all的then回调内部,或者await Promise.all的下一行,此时异步请求已经全部完成,打印的就是完整填充后的结果。 - 如果需要在其他文件中调试
list,直接在调用异步函数拿到返回值后打印即可,不需要在第一个文件中导出变量。
内容的提问来源于stack exchange,提问作者ByAdham
相关产品推荐
相关产品推荐

