每次我在我的应用中添加新项目时,由于某种原因,突变会调用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"
}
我在这里做错了什么?
答案 0 :(得分:4)
我刚刚与处理此代码的工程师聊了聊。您所看到的是AWS AppSync SDK流程在底层使用的bookeeping流程,以确保数据的完整性。 NOT 实际上针对您的API运行了4次变异。
当AppSync客户端获得乐观响应时,更新功能会运行两次 - 一次用于本地响应,一次用于网络响应。这是标准的阿波罗行为。 AppSync客户端在第一个乐观响应中做了什么,我们将其视为网络响应并将数据存储在持久存储介质(Web的本地存储,React Native的异步存储)中以允许乐观的UI处于离线状态时这本质上是一个"发件箱"数据首次在离线时写入(当前实施使用Redux离线),如果您使用disableOffline:true
禁用离线,则不会再看到此行为。
当你重新上线时,同步过程会被执行,你会看到客户端发送给服务器的另一条突变消息(实际上是原始的突变)以及相应的响应。
请注意,如果您在客户端上的乐观响应中创建唯一ID并在服务器上创建唯一ID,例如使用$util.autoId()
,那么您可能会有重复记录,因为我们不会覆盖任何本地数据您已明确分配了ID。如果您希望在AppSync的DynamoDB解析器中使用启用离线的放置项和启用脱机的响应模板,则可以使任何本地创建的ID无效名为relayState
的短暂密钥(您需要添加为您正在创建的类型的字段),您可以使用该密钥跟踪本地ID并将其与创建的ID进行匹配在服务器上。
我们将来还会对此博客流程做出更多补充,欢迎在我们的GitHub问题回复中提出建议:https://github.com/awslabs/aws-mobile-appsync-sdk-js/issues