JavaScript中如何获取dataReal函数内部的处理结果到外部使用
问题原因
你遇到的问题分两类:
- 基础复现代码的问题是执行顺序错误:你在调用
dataReal给data赋值之前就打印了data,此时data还没被修改,自然输出null。 - 补充场景的问题有两个:
- 你在
user.js顶层直接调用dataReal(val)时,val没有被赋值,自然报val未定义的错误 - axios是异步请求,
user.js顶层的console.log(data)在模块加载时就会执行,此时axios请求还没返回,dataReal还没被调用,data自然还是null
- 你在
解决方案
基础场景修复
只要调整执行顺序,先调用函数赋值,再读取变量即可:
var data = null; function dataReal(val) { data = JSON.parse(val); console.log(data); // Result object : {users: Array(3), permission: Array(8)} } // 先调用函数赋值 dataReal('{"users": [1,2,3], "permission": []}') // 再读取变量 console.log(data); // 此时输出处理后的对象
Vue项目场景修复
你可以根据自己的需求选以下任意一种方案:
方案1:直接返回处理结果,在异步回调中读取
修改user.js,去掉无意义的顶层调用和打印,直接导出处理逻辑:
// user.js export function dataReal(val) { const data = JSON.parse(val); console.log(data); // 把处理后的结果返回 return data }
在User.vue的异步回调中读取返回值:
<script> import { dataReal } from './user.js' export default { props: { msg: String, }, created() { const userId = this.$route.params.id; axios .get("/project/api/users/" + userId) .then((res) => { // 接收处理后的结果 const data = dataReal(res.data); // 这里直接用结果就行,要存到组件data里直接赋值即可 console.log(data); }) .catch((error) => { console.log(error); }); }, } </script>
方案2:封装成异步函数统一处理请求
如果请求逻辑要复用,可以把整个请求和处理逻辑封装到user.js里:
// user.js export async function getUserData(userId) { const res = await axios.get(`/project/api/users/${userId}`) return JSON.parse(res.data) }
在User.vue中直接调用:
<script> import { getUserData } from './user.js' export default { props: { msg: String, }, async created() { const userId = this.$route.params.id; try { const data = await getUserData(userId) // 拿到处理后的结果 console.log(data) } catch (error) { console.log(error) } }, } </script>
方案3:跨组件共享数据用状态管理
如果多个组件都要用到这个用户数据,建议用Vue官方的Pinia做状态管理,避免全局变量污染,同时自带响应式:
// stores/user.js import { defineStore } from 'pinia' export const useUserStore = defineStore('user', { state: () => ({ userData: null }), actions: { async fetchUserData(userId) { const res = await axios.get(`/project/api/users/${userId}`) this.userData = JSON.parse(res.data) } } })
在User.vue中调用:
<script> import { useUserStore } from '@/stores/user.js' export default { props: { msg: String, }, async created() { const userStore = useUserStore() const userId = this.$route.params.id; try { await userStore.fetchUserData(userId) // 直接从store取数据,其他组件也能直接访问 console.log(userStore.userData) } catch (error) { console.log(error) } }, } </script>
注意事项
- 所有异步操作的结果,必须在异步回调、
await之后的代码中才能读取,同步代码执行时异步请求还没返回,必然拿不到结果 - 不要在模块顶层直接调用依赖外部参数或者异步返回值的函数,模块顶层代码只会在首次加载时执行一次,此时参数还没赋值
- 不建议用全局变量存储共享数据,容易引发变量污染和数据同步问题
内容的提问来源于stack exchange,提问作者deskeay
相关产品推荐
相关产品推荐

