数据显示在 websocket 响应中,但未显示在已解决的承诺中

Posted

技术标签:

【中文标题】数据显示在 websocket 响应中,但未显示在已解决的承诺中【英文标题】:Data shows up in websocket response but not in resolved promise 【发布时间】:2018-10-22 11:53:33 【问题描述】:

我正在使用 Nuxt + Express/Feathers 构建一个应用程序,两者通过 socket.io 连接进行通信。使用 feathers-vuex,我可以轻松地从客户端向后端发出请求,并且响应完美地返回到 chrome 检查器的网络选项卡中,但在我的代码中已解决的承诺中,每个返回的对象都是 undefined

Websocket 请求:

4235["find", "journals", ]

Websocket 响应:

4335[null, total: 3, limit: 10, skip: 0,…]
0: null
1: total: 3, limit: 10, skip: 0,…
  data: [_id: "5af62077f2389a7490be22d6", _id: "5af62094f2389a7490be22d7", some: "data",…]
    0: _id: "5af62077f2389a7490be22d6"
    1: _id: "5af62094f2389a7490be22d7", some: "data"
    2: _id: "5af66b3ae8c629789f35ead3", name: "john", surname: "doe"
  limit: 10
  skip: 0
  total: 3

这就是results 在调试器中的样子:

total: 3, limit: 10, skip: 0, data: Array(3)
  data: Array(3)
    0: undefined
    1: undefined
    2: undefined
    length: 3
    __proto__: Array(0)
  limit: 10
  skip: 0
  total: 3
  __proto__:
    ...

这是我提出请求的 Nuxt 页面部分:

<template>
  <h1>journals</h1>
  <button class="btn btn-primary" @click="findThoseJournals()">
    Search Journals
  </button>
</template>

<script>
import  mapActions  from 'vuex';
export default 
  data () 
    return 
      journals: []
    
  ,
  methods: 
    ...mapActions('journals', 
      findJournals: 'find'
    ),
    findThoseJournals() 
      this.findJournals(query: ).then((results) => 
        debugger;
        this.journals = results.data;
      );
    
  ,

</script>

为了记录,results.data 在渲染时看起来像 [null,null,null]。

我完全不知道是什么导致了这种行为。为什么元数据会延续,而数据本身却没有(但 number 的条目仍然如此)?在 websocket 帧响应和专门导致数据消失的承诺之间发生了什么?

【问题讨论】:

你在哪里打电话findThoseJournals?你能展示更多的组件和相关的 Vuex 模块吗? 添加了相关细节!只有未显示的位是额外的 div 和 我没有看到 findJournals 的 vuex 操作... 它是来自 feathers-vuex 的服务模块的一部分 - 不过,这里有一个指向源代码的链接:link 【参考方案1】:

找出问题所在。在feathers-vuex 操作中抛出了一些调试器,并意识到我没有在我的feathersClient 配置中将idField 设置为_id

【讨论】:

【参考方案2】:

如果没有在 Vuex 商店中看到您的 findJournals 操作代码,我只能想象您没有在操作中返回 Promise。看看这个例子:https://codesandbox.io/s/6w97yx0yo3。如果您在 loadSomeUsers 中没有 return,则您在组件中返回的响应是 undefined,而不是所需的有效负载。

【讨论】:

【参考方案3】:

.findJournals() 是异步的。这意味着该方法在获得结果之前很久就返回了。您没有向我们展示调用.findJournals() 的代码,但是按照您的结构方式,调用代码无法访问.journals 属性,因为当.findJournals() 返回时它不会被设置.所以,你需要做的是返回promise,让调用者使用这个promise来获取结果。

findThoseJournals() 
  // return promise
  return this.findJournals(query: );

然后,调用者会这样做:

someObj.findThoseJournals().then(journals => 
    // use journals here
);

【讨论】:

抱歉,我不认为我理解您的示例(在包装函数中解析承诺)和在同一函数中解析承诺之间的区别。根据定义,函数不是一直在等待返回,直到 promise 以任何一种方式解决?我对此也可能大错特错,但考虑到元数据已返回并且数据数组的大小正确,似乎响应正在及时做出。虽然我确实看到了一个不完整的字节串如何可能返回一个未定义对象的数组,而完整的版本将包含这些对象。 我并不是要表现得不感恩或好斗 - 我只是想确保我在自己的推理中发现了任何错误。 @Cameron - 不,这就是整个问题。该函数立即返回,并且承诺会在一段时间后解决。 Promise 不会阻塞。 @Cameron - 承诺的全部意义在于承诺立即返回,然后一段时间后,承诺通知其观察者该值可用。这就是我们使用 Promise 的原因。在获得值之前,Promise 不会阻止函数返回。

以上是关于数据显示在 websocket 响应中,但未显示在已解决的承诺中的主要内容,如果未能解决你的问题,请参考以下文章

如何在 NodeJS 中显示 Websocket 对浏览器的响应

如何在浏览器中显示大量 websocket 消息?

在 div 下拉菜单之外单击时隐藏,但未显示切换

W7系统,显示文件和打印共享资源处于联机状态,但未对连接尝试做出响应!

迁移成功但未显示在数据库中

在 mysql 中创建数据库但未在 phpmyadmin 中显示