JavaScript异步函数传值异常:Promise下函数结果传递问题排查
问题分析与解决方案
你的核心问题在于**fetchData函数没有返回异步操作的结果**,它同步返回了一个空数组,导致await完全起不到作用。
为什么会出现这种情况?
d3.csv()是异步操作,会返回一个Promise,你在.then()里填充fetched数组,但函数在.then()的代码执行前就已经同步返回了初始的空fetched数组。
- IDE提示
await无用:因为fetchData返回的是普通数组,不是Promise,await只能作用于Promise,所以这个提示是对的。 - 控制台能显示数组但遍历无输出:浏览器控制台会动态更新对象/数组的引用显示,当后续
.then()里的代码填充了数组,控制台会更新显示,但此时parseData里的遍历已经执行完毕(遍历是同步的,执行时数组还是空的),所以没有输出。
修正方案
让fetchData返回一个Promise,这样await才能正确等待异步操作完成。有两种写法:
写法1:直接返回Promise链
const fetchData = (data) => { // 直接返回d3.csv的Promise处理结果 return d3.csv(data).then(csv_file => { const fetched = []; for (let c in csv_file) { fetched.push(csv_file[c]["Sentence"]); } return fetched; // 这里返回的数组会成为Promise的resolve值 }); }
写法2:用async/await重构fetchData
const fetchData = async (data) => { const csv_file = await d3.csv(data); // 等待csv加载完成 const fetched = []; for (let c in csv_file) { fetched.push(csv_file[c]["Sentence"]); } return fetched; // async函数自动把返回值包装成Promise }
修正后的parseData执行效果
此时再运行你的parseData函数:
const parseData = async (data) => { let parsed = await fetchData(data); for (let p of parsed) { console.log(p); // 现在能正确遍历输出每个句子了 } }
await会等待fetchData的Promise resolve,拿到填充好的数组,遍历自然能输出内容。
额外优化:遍历方式
你用for...in遍历数组其实不太合适,for...in是为遍历对象属性设计的,遍历数组更推荐用for...of或者Array.prototype.forEach:
// 比如在fetchData里换成forEach csv_file.forEach(item => { fetched.push(item.Sentence); });
内容的提问来源于stack exchange,提问作者Louloumonkey
相关产品推荐
相关产品推荐

