小编Mik*_*ert的帖子

阿波罗突变去抖和竞争条件

(这是对https://github.com/apollographql/apollo-client/issues/1886的跟进)

我正在尝试构建一个文本输入,它将在用户输入时更新值.

第一次尝试

我首先尝试使用optimisticResponse更新本地缓存作为用户类型.这是有效的,除了它会在每次击键时触发突变.除了通过请求充斥网络之外,还存在网络不一致的问题.最后一个突变可能首先到达,第一个突变最后到达.这导致服务器以过时值结束.以下是此竞争条件的示例:

type: a
mutate request: a
type: b
mutate request: ab
arrives on server: ab
arrives on server: a
Run Code Online (Sandbox Code Playgroud)

现在服务器在graphql中记录了"a",这是不正确的.

添加去抖动

为了缓解这个问题,我对按键事件进行了辩论.虽然这确实有助于上述竞争条件,但它并没有解决它.如果网络比你的去抖阈值慢,那么仍有可能出现竞争条件.

因为我们现在正在对文本输入进行去抖动,所以我们需要向该React组件引入一个本地状态,以便在用户输入时立即更新(如github问题中建议的@jbaxleyiii).现在我们的状态位于两个位置(组件状态和apollo缓存).

这个问题的一个大问题是组件在收到新道具时不会更新.例如.当graphql更新并推送到客户端时.

添加网络队列

因为debounce实际上并没有解决竞争条件,所以我添加了一个网络队列(除了去抖动),它将管理变异请求,以确保一次只有一个变异.如果在飞行中有一个突变请求时它会收到突变请求,它会将它排队等待第一个返回时被触发.如果已经有一个排队的突变,它将丢弃它并将其替换为新的突变(一次只能有一个项目在队列中).这是一个例子:

type: a
send mutate request: a
type: b
queues mutate request: ab     <<  wait to send this until "a" comes back
type: c
replaces queued request: abc  << discard the queued request for "ab", it's old now
response from server: a
send mutate request: abc …
Run Code Online (Sandbox Code Playgroud)

apollo reactjs graphql react-apollo

7
推荐指数
1
解决办法
1333
查看次数

标签 统计

apollo ×1

graphql ×1

react-apollo ×1

reactjs ×1