来自 Promise 的数据永远不会在组件中呈现
Posted
技术标签:
【中文标题】来自 Promise 的数据永远不会在组件中呈现【英文标题】:Data from promise never renders in component 【发布时间】:2020-12-21 20:36:56 【问题描述】:在 NativeScript-Vue/Firebase 中,我有一个带有 promise 的方法,它应该从当前用户的关联 Firestore 文档中获取一组文档 uid。 uid 对应于与其他用户关联的文档(当前用户正在关注的用户”,也就是他们的“圈子”)。
Firestore 数据如下所示:
使用 vue-devtools,它会在页面的数据中显示 circleList 被正确的数据数组填充。问题是,它永远不会在 Listview 中呈现,并且 isLoading 永远不会更改为 false。我的假设是组件在加载数据之前尝试渲染。我尝试使用 async/await 来解决这个问题,但它使来自 Vuex 的 userProfile 信息也永远不会呈现。
代码如下所示:
<template>
<Page>
<StackLayout>
<Label text="Loading" v-if="isLoading"/>
<Listview for="item in circleList" v-else>
<Label :text="item.name"/>
</Listview>
</StackLayout>
</Page>
</template>
<script>
import mapState from "vuex";
const firebase = require("nativescript-plugin-firebase/app");
const userDataCollection = firebase.firestore().collection("userDataCollection");
export default
data()
return
isLoading: true,
circleList: [],
item:
,
created()
this.getCircle();
,
computed:
...mapState(['userProfile'])
,
methods:
getCircle()
var circle = this.userProfile.circle
const promises = circle.map(u => userDataCollection.doc(u).get())
return Promise.all(promises).then(results =>
results.map(docSnapshot =>
this.circleList.push(docSnapshot.data())
this.isLoading = false
)
)
;
【问题讨论】:
我不建议在地图内进行突变。在此处使用 forEach 或普通循环。使用地图的正确方法如下:this.circleList = results.map(docSnapshot => docSnapshot.data()); this.isLoading = false;
userProfile.circle
也是异步数据,还是静态的?
userProfile.circle 在 Vuex 中是异步的。
【参考方案1】:
由于 userProfile 也是异步的,因此您必须等待它解析才能在 getCircle 中执行第一个映射。
我喜欢这样做的方式是为 userProfile 创建一个返回承诺的操作。该操作将首先检查状态中是否存在 userProfile。如果有,它只会返回 userProfile,如果没有,它将获取它然后返回:
const actions =
getUserProfile(state)
return new Promise((resolve, reject) =>
if (state.userProfile)
resolve(state.userProfile);
return;
// UserProfile is not yet fetched, so fetch it, add it to state.userProfile
// and resolve the response so you can use it in Vue
)
由于这个动作现在返回一个承诺,你可以在 Vue 中等待它:?
created()
this.getCircle();
,
methods:
...mapActions(['getUserProfile']),
async getCircle()
let circle = [];
try
const userProfile = await this.userProfile();
circle = userProfile.circle;
catch (error)
// Some error handling here
const promises = circle.map(u => userDataCollection.doc(u).get())
Promise.all(promises).then(results =>
this.circleList = results.map(docSnapshot => docSnapshot.data())
this.isLoading = false;
)
【讨论】:
以上是关于来自 Promise 的数据永远不会在组件中呈现的主要内容,如果未能解决你的问题,请参考以下文章
VueJS 组件不会在前端呈现(可能是 Drupal 问题)