【问题标题】:Graphql subscriptions or pollInterval ? Differences in different cases?Graphql 订阅或 pollInterval ?不同情况下的区别?
【发布时间】:2021-04-10 14:22:41
【问题描述】:

我目前正在观看使用 MERNG 堆栈的课程,它基本上是一个发布内容的应用程序,而我自己试图实现的目标是实时向所有用户发布帖子,所以,我的第一个想法是,好吧,让我们使用 graphql 订阅,并使用 apollo/client 做出反应,我编写了这段代码来实时获取新帖子

import React, { useContext } from "react";
import { useQuery, useSubscription, gql } from "@apollo/client";
import { Grid } from "semantic-ui-react";

import { AuthContext } from "../context/auth";
import PostCard from "../components/PostCard";
import PostForm from "../components/PostForm";

import { FETCH_POSTS_QUERY } from "../util/graphql";

const Home = () => {
  const { user } = useContext(AuthContext);

  const { loading, data: { getPosts: posts } = {} } = useQuery(
    FETCH_POSTS_QUERY,
    // {
    //   pollInterval: 500
    // }
  );

  const { data: { newPost: post } = {} } = useSubscription(POSTS_REAL_TIME);

  return (
    <Grid columns={3}>
      <Grid.Row className="page-title">
        <Grid.Column>
          <h1>Recent Posts</h1>
        </Grid.Column>
      </Grid.Row>
      <Grid.Row>
        {user && (
          <Grid.Column>
            <PostForm />
          </Grid.Column>
        )}
        {loading ? (
          <h1>Loading Posts...</h1>
        ) : (
          posts &&
          posts.map(post => {
            return (
              <Grid.Column key={post.id} style={{ marginBottom: "20px" }}>
                <PostCard post={post} />
              </Grid.Column>
            );
          })
        )}
      </Grid.Row>
    </Grid>
  );
};

const POSTS_REAL_TIME = gql`
  subscription {
    newPost {
      id
      body
      createdAt
      username
      likes {
        username
      }
      likeCount
      comments {
        id
        username
        createdAt
      }
      commentCount
    }
  }
`;

export default Home;

我当时想,好吧,但是...我无法在页面中显示它们,因为我不知道如何将该对象推送到来自我的 useQuery 一开始的帖子数组中

所以我看看如何让客户端更新订阅,我发现一个帖子显示了 graphql 的文档,说你不应该使用订阅更新你的客户端,而是使用 轮询间隔

const { loading, data: { getPosts: posts } = {} } = useQuery(
    FETCH_POSTS_QUERY,
    {
      pollInterval: 500
    }
  );

所以,这实际上意味着,我花了 2 个小时尝试一个奇怪的代码,而我只需要一行代码就可以做到这一点,那么 pollInterval 会取代订阅吗?我应该如何使用订阅?如果我使用 pollInterval 让每个人都保持最新状态,这对性能有影响吗?

感谢您的时间社区!

【问题讨论】:

  • 它的推与拉。拜访奶奶时,投票间隔是孩子每隔几分钟问“我们到了吗”。订阅是在整个过程中小睡以在抵达时被唤醒的孩子。它们都有优点和缺点,适合不同的用例。持续更新受益于订阅。如果你只每隔几个小时更新一次,那么让 websocket 保持打开状态就是一种浪费。
  • 酷伙伴,谢谢你的回答,所以我想如果我使用 pollInterval,就可以做我想做的事了!

标签: reactjs graphql


【解决方案1】:

我认为问题不在于您的订阅不起作用,而是您希望将旧数据保留在视图中,并让新帖子进入。您需要做的是将旧数据保持在 React 状态或使用阿波罗状态/缓存。因此,您无需使用新帖子更新视图,而是使用最新帖子更新状态,从而强制重新渲染您的组件。

【讨论】:

  • 是的,我的意思是,pollInterval 基本上在做的是,在 500 毫秒前调用 useQuery 以了解是否有已知的更新内容
【解决方案2】:

我不是专家,但我认为轮询不是完成这项工作的正确方法,因为您会不断尝试刷新数据,并且会浪费服务器上的资源。我会使用订阅(Apollo ServerApollo Client(react))或类似socket.io 的东西,它们都在底层使用 websockets,所以没有太大区别。

【讨论】:

  • 这就是我的想法,但是,您使用的是graphql吗?您可以使用订阅,因为它使用网络套接字,所以没有理由使用socket.io,但我想不通如何将我订阅的新对象添加到我当前的数据中:/
猜你喜欢
  • 1970-01-01
  • 2021-08-12
  • 1970-01-01
  • 2016-10-27
  • 2020-04-19
  • 2021-12-21
  • 2021-02-01
  • 2022-01-17
  • 1970-01-01
相关资源
最近更新 更多