Оптимистичный интерфейс для подписок Apollo js

Имеет ли смысл иметь оптимистичный интерфейс с подписками?

Итак, в основном:

addChannelMutation({
  variables: { name: eventValue },
  optimisticResponse: {
    __typename: "Mutation",
    addChannel: {
      __typename: "Channel",
      id: data.channels.length,
      name: eventValue
    }
  },
  update: (store, { data: { addChannel } }) => {
    // Read the data from our cache for this query.
    const data = store.readQuery({ query: channelsListQuery });
    // Add our comment from the mutation to the end.
    data.channels.push(addChannel);
    // Write our data back to the cache.
    store.writeQuery({ query: channelsListQuery, data });
  }
}).then(res => {});

Он добавляет дважды один и тот же элемент, вызывая исключение повторяющегося ключа. Таким образом, имеет ли смысл оптимистичный интерфейс с подписками?


person Luca Marangon    schedule 18.05.2017    source источник


Ответы (1)


optimisticResponse запускает update перед тем, как сервер получит ответ. Затем, когда сервер отвечает, снова запускается update и заменяет оптимистичный заполнитель ответом.

Подписки будут генерироваться только после разрешения мутации сервера, то есть, по сути, когда сервер отвечает.

Если вы не включили Optimistic UI и у вас была какая-то задержка, результат не будет отображаться, пока сервер не отправит ответ. Это может быть проблемой, например, в приложении чата, если пользователь не видит свое сообщение, как только нажимает кнопку отправки. Они будут нажимать кнопку и отправлять сообщение несколько раз: /

Для борьбы с обманами при использовании Optimisic UI и подписок используются две стратегии:

  1. проверить на дурак на клиенте:

    в функциях update и updateQuery:

    // super simplified dupe doc checker
    function isDuplicateDocument(newDocument, existingDocuments) {
      return newDocument.id !== null && existingDocuments.some(doc => newDocument.id === doc.id);
    }
    
    addChannelMutation({
      variables: { name: eventValue },
      optimisticResponse: {
        __typename: "Mutation",
        addChannel: {
          __typename: "Channel",
          id: data.channels.length,
          name: eventValue
        }
      },
      update: (store, { data: { addChannel } }) => {
        // Read the data from our cache for this query.
        const data = store.readQuery({ query: channelsListQuery });
        if (isDuplicateDocument(addChannel, data.channels) {
          return;
        }
    
        // Add our comment from the mutation to the end.
        data.channels.push(addChannel);
        // Write our data back to the cache.
        store.writeQuery({ query: channelsListQuery, data });
      }
    }).then(res => {});
    

    А также внутри updateQuery в вашей подписке:

    subscribeToMore({
      ...
      updateQuery: (previousResult, { subscriptionData }) => {
        const newChannel = subscriptionData.data.addChannel;
        // if it's our own mutation
        // we might get the subscription result
        // after the mutation result.
        if (isDuplicateDocument(
          newChannel, previousResult.channels)
        ) {
          return previousResult;
        }
    
        return update(previousResult, {
          channels: {
            $push: [newChannel],
          },
        });
      },
    
  2. Или вы можете ограничить свою подписку на сервере, чтобы не отправлять создателю нового канала.

person srtucker22    schedule 23.05.2017
comment
Спасибо. Именно этим я и занимаюсь. - person Luca Marangon; 23.05.2017