来自 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 =&gt; 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 的数据永远不会在组件中呈现的主要内容,如果未能解决你的问题,请参考以下文章

来自祖父母的组件,来自父母的数据,在孩子中呈现

当 Promise 永远不会解决时会发生啥? [复制]

fetch Promise 永远不会被执行

VueJS 组件不会在前端呈现(可能是 Drupal 问题)

Vue Typescript 组件 Jest 测试不会在 html 中呈现值

React 组件在来自 JSON 对象的选项卡中呈现动态内容