You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

在Apollo-Angular中何时使用watchQuery与query?二者逻辑及差异解析

Hey there! Let's break down the differences between watchQuery and query in Apollo-Angular—this is such a common question once you start building with GraphQL in Angular, so I’m glad you’re digging into the details.


Core Logic

Let’s start with the basics of what each method actually does:

query()

This is your one-time data fetch workhorse. When you call query(), it:

  1. Checks Apollo’s local cache first (using the default cache-first fetch policy) to see if the data already exists.
  2. If the cache doesn’t have the data, it sends a single HTTP request to your GraphQL server.
  3. Returns an Observable that emits exactly one result (the data from cache or server) and then completes.
  4. No further updates—unless you explicitly call query() again.

watchQuery()

This is your real-time, reactive data listener. It’s designed to keep your UI in sync with both the local cache and remote data. When you initialize watchQuery():

  1. Starts by fetching the initial data (again, checking cache first by default).
  2. Returns an Observable that keeps emitting new data whenever:
    • The GraphQL server returns an updated response (e.g., if you use pollInterval to refresh periodically).
    • The local Apollo cache is modified by another operation (like a mutation or another query updating the same data).
  3. The Observable stays active until you unsubscribe from it—so it’s always listening for changes.

Ideal Use Cases

Knowing when to pick which method will save you from unnecessary network calls or stale UI:

Use query() when:

  • You need data once for a static view (e.g., loading a user’s profile page that doesn’t need to update unless the user refreshes).
  • You’re fetching data as part of a one-time action (e.g., after submitting a form, you fetch the updated list once).
  • You want minimal overhead—since it doesn’t maintain a persistent subscription, it’s lighter for non-reactive use cases.

Use watchQuery() when:

  • Your UI needs to update automatically when data changes (e.g., a chat room showing new messages, a dashboard reflecting real-time metrics).
  • Other parts of your app might modify the same data (e.g., if a mutation updates a product’s stock, you want the product list to refresh instantly).
  • You need to implement features like infinite scroll or pagination where new data loads and adds to the existing dataset.
  • You want to use Apollo’s built-in polling (via pollInterval option) to regularly refresh data from the server.

Key Differences at a Glance

Aspectquery()watchQuery()
Data EmissionsSingle emission, then completesContinuous emissions on cache/server changes
Cache InteractionOnly checks cache once on initial callListens for cache updates indefinitely
Subscription LifecycleObservable completes after first emissionObservable stays active until unsubscribed
OverheadLightweight, no persistent subscriptionSlightly heavier due to ongoing listening
Polling SupportNo built-in pollingSupports pollInterval for periodic refreshes

Quick Code Examples

Let’s see how these look in Angular:

query() Example

import { Apollo } from 'apollo-angular';
import gql from 'graphql-tag';
import { map } from 'rxjs/operators';

@Component({ template: '<div *ngIf="user$ | async as user">{{ user.name }}</div>' })
export class UserProfileComponent implements OnInit {
  user$: Observable<User>;

  constructor(private apollo: Apollo) {}

  ngOnInit() {
    this.user$ = this.apollo.query({
      query: gql`
        query GetUser($id: ID!) {
          user(id: $id) {
            id
            name
            email
          }
        }
      `,
      variables: { id: 'user-123' }
    }).pipe(
      map(result => result.data.user)
    );
  }
}

This fetches the user once and displays it—no automatic updates.

watchQuery() Example

import { Apollo } from 'apollo-angular';
import gql from 'graphql-tag';
import { map, Subscription } from 'rxjs';

@Component({ template: '<div *ngFor="let msg of messages$ | async">{{ msg.content }}</div>' })
export class ChatComponent implements OnInit, OnDestroy {
  messages$: Observable<Message[]>;
  private subscription: Subscription;

  constructor(private apollo: Apollo) {}

  ngOnInit() {
    const watcher = this.apollo.watchQuery({
      query: gql`
        query GetChatMessages($roomId: ID!) {
          chatMessages(roomId: $roomId) {
            id
            content
            sender
          }
        }
      `,
      variables: { roomId: 'chat-room-456' },
      pollInterval: 3000 // Refresh from server every 3 seconds
    });

    this.messages$ = watcher.valueChanges.pipe(
      map(result => result.data.chatMessages)
    );

    // If not using async pipe, remember to unsubscribe!
    this.subscription = this.messages$.subscribe();
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

This will automatically update the message list whenever new messages are added to the cache (via mutation) or the server returns fresh data every 3 seconds.


内容的提问来源于stack exchange,提问作者yussenn

火山引擎 最新活动