1

每次我在我的应用程序中添加一个新项目时,由于某种原因,突变会调用update() 四次。前两个是乐观数据,第二批,一个是乐观数据,一个是来自网络的真实数据。我无法理解这一点。正在创建的新项目在页面上显示两次。

这是我的突变:

mutation CreateTrack($name: String!, $trackNum: Int, $s3Key: String!) {
  createTrack(name: $name, trackNum: $trackNum, s3Key: $s3Key) {
    trackId
    name
    createdAt
    duration
    trackNum
    s3Key
    isProcessing
    didProcessingFail
  }
}

这是突变代码:

createTrack({ name, s3Key }) {
  const newTrack = {
    name,
    s3Key,
  };

  this.$apollo
    .mutate({
      mutation: createTrackMutation,
      variables: newTrack,
      update: (store, { data: { createTrack } }) => {
        console.log('this is dumb', JSON.stringify(createTrack, null, 2));
        const variables = {
          limit: this.pageSize,
          order: this.order === 'ascending' ? 'asc' : 'desc',
          sortBy: this.sortBy,
        };
        const data = store.readQuery({
          query: listTracksQuery,
          variables,
        });
        data.listTracks.items.push(createTrack);
        store.writeQuery({
          query: listTracksQuery,
          variables,
          data,
        });
      },
      optimisticResponse: {
        __typename: 'Mutation',
        createTrack: {
          __typename: 'Track',
          ...newTrack,
          trackId: '??',
          createdAt: new Date().toISOString(),
          isProcessing: true,
          didProcessingFail: false,
          duration: null,
          trackNum: 999,
        },
      },
    })
    .then(data => {
      console.log('done!', data);
    })
    .catch(err => {
      console.log('error', err);
    });
},

最后,这里是调用 mutate一次的控制台日志:

this is dumb {
  "__typename": "Track",
  "name": "small2.wav",
  "s3Key": "staging/audio/10e3e675-e7a6-41dc-a8fb-686ad683e40e.wav",
  "trackId": "??",
  "createdAt": "2018-03-05T03:30:18.246Z",
  "isProcessing": true,
  "didProcessingFail": false,
  "duration": null,
  "trackNum": 999
}

this is dumb {
  "__typename": "Track",
  "name": "small2.wav",
  "s3Key": "staging/audio/10e3e675-e7a6-41dc-a8fb-686ad683e40e.wav",
  "trackId": "??",
  "createdAt": "2018-03-05T03:30:18.246Z",
  "isProcessing": true,
  "didProcessingFail": false,
  "duration": null,
  "trackNum": 999
}

done! {data: {...}}

this is dumb {
  "__typename": "Track",
  "name": "small2.wav",
  "s3Key": "staging/audio/10e3e675-e7a6-41dc-a8fb-686ad683e40e.wav",
  "trackId": "??",
  "createdAt": "2018-03-05T03:30:18.246Z",
  "isProcessing": true,
  "didProcessingFail": false,
  "duration": null,
  "trackNum": 999
}

this is dumb {
  "trackId": "2b3de8ac-d145-4da6-b522-27e5413d43e1",
  "name": "small2.wav",
  "createdAt": "2018-03-05T03:30:18.627Z",
  "duration": null,
  "trackNum": 999,
  "s3Key": "staging/audio/10e3e675-e7a6-41dc-a8fb-686ad683e40e.wav",
  "isProcessing": true,
  "didProcessingFail": null,
  "__typename": "Track"
}

我在这里做错了什么?

4

1 回答 1

4

我刚刚与处理此代码的工程师聊了聊。您所看到的是 AWS AppSync 开发工具包流程在幕后使用的簿记流程,以确保数据完整性。它实际上并没有针对您的 API 运行 4 次突变。

当 AppSync 客户端获得乐观响应时,更新函数会运行两次 - 一次用于本地响应,一次用于网络响应。这是标准的 Apollo 行为。AppSync 客户端在幕后所做的是在第一个乐观响应上,我们将其视为网络响应并将数据存储在持久存储介质(Web 的本地存储,React Native 的异步存储)中以允许乐观的 UI处于离线状态时。这本质上是一个“发件箱”,数据在离线时首先被写入(当前实现使用 Redux Offline),如果您禁用离线,disableOffline:true您将不再看到此行为。

当您重新联机时,同步过程将被执行,您会看到客户端的另一个突变消息(实际上是原始突变)将其发送到服务器和适当的响应。

请注意,如果您在客户端的乐观响应中创建唯一 ID,并且还在服务器上创建唯一 ID,例如使用 ,$util.autoId()那么您可能会有重复的记录,因为我们不会覆盖您明确分配的任何本地数据 ID。如果您愿意,您可以通过在 AppSync 的 DynamoDB 解析器中使用启用离线的放置项启用离线的响应relayState模板来使任何本地创建的 ID 失效,这些模板使用名为的临时键(您需要将其添加为字段对于您正在创建的类型),您可以使用它来跟踪本地 ID 并将其与在服务器上创建的 ID 匹配。

我们将在未来对该簿记流程进行更多补充,并欢迎在我们的 GitHub 问题存储库中提出建议:https ://github.com/awslabs/aws-mobile-appsync-sdk-js/issues

于 2018-03-06T23:21:37.633 回答