如何将async函数中fetch返回的Promise响应结果保存到外部变量
你遇到的所有问题本质上都是JS异步代码执行机制导致的,以下是具体说明和解决方案:
执行顺序问题的核心原因
JS主线程不会等待异步操作完成再执行后续代码:
- 所有
async函数只要遇到await或者发起异步请求(比如fetch),就会立刻返回一个Pending状态的Promise对象,主线程会直接往下跑后面的同步代码。 - 你写的
alert(getData('./2021WeatherData.csv'))拿到的就是这个刚返回的Promise,所以会先弹出[object Promise],等后面fetch请求完成、内部的.then回调触发时,才会弹出文件内容。 - 全局变量的例子里,
alert(theData)执行时fetch请求还没完成,theData还没被赋值,所以只会弹出初始值blank。
调用getData().text()报错的原因
.text()是fetch返回的Response实例的专属方法,而async函数返回的是Promise对象,两者不是同一个类型,自然会报“text不是函数”的错误。
正确获取外部可用数据的方案
所有依赖异步请求结果的逻辑,必须等异步操作完成后再执行,常用两种写法:
方案1:通过.then链式调用获取结果
async function getData(filePath) { try { const response = await fetch(filePath) // 直接将结果返回,async会自动把它包装为Promise的resolve值 return await response.text() } catch (error) { alert(error) } } // 调用时在.then回调中处理数据,所有需要用到数据的逻辑都要放在回调内 getData('./2021WeatherData.csv').then(data => { // 这里可以正常使用数据,也可以赋值给全局变量供其他逻辑调用 const theData = data alert(theData) // 后续处理逻辑写在这里 processWeatherData(theData) })
方案2:顶层await(适用环境:ES模块脚本、NodeJS 14.8+)
如果你的运行环境支持顶层await,可以直接用await拿到结果:
let theData = 'blank' async function getData(filePath) { const response = await fetch(filePath) return await response.text() } // 直接用await等待异步操作完成 theData = await getData('./2021WeatherData.csv') alert(theData) // 这里可以拿到正确的文件内容
额外说明
你提到的所有操作触发两次的问题,大概率是页面脚本重复加载、框架组件重复渲染导致的,和异步逻辑本身无关,可以单独排查下页面引入逻辑。
内容的提问来源于stack exchange,提问作者SunnyNonsense
相关产品推荐
相关产品推荐

