js实现超简单setState事务机制

广告位招租
扫码页面底部二维码联系

在撰写hst-virtuanl-dom的著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。过程中,和react的setState一【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net样,我希望合并多个短时间内的update原创内容,盗版必究。转载请注明出处:www.tangshuang.net操作。比如在极短的时间内执行了两个upd未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。ate,如果每一个update都去刷新界【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】面,这显然是没有必要的。因此,应该考虑一未经授权,禁止复制转载。【原创不易,请尊重版权】种事务机制,来实现将它们合并的目的,即短【转载请注明来源】原创内容,盗版必究。时间内的多个update合并为一个视图的【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。更新。

【原创不易,请尊重版权】【原创内容,转载请注明出处】原创内容,盗版必究。本文作者:唐霜,转载请注明出处。

react的setState是一个很难把【未经授权禁止转载】本文作者:唐霜,转载请注明出处。握的操作,它是完全异步的,导致用setS【本文受版权保护】【版权所有】唐霜 www.tangshuang.nettate更新数据之后,不能马上得到新的数著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】据,比如:

【转载请注明来源】【未经授权禁止转载】著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】
this.setState({ name: 'tony' })
console.log(this.state.name) // 不是tony,而是当前的state.name

要得到新的state值,必须在setSt【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。ate的第二个参数中传入一个回调函数,用【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.net来得到更新后的state。但是蛋疼的是,转载请注明出处:www.tangshuang.net【本文受版权保护】如果短时间内执行了多个setState,本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】那么回调中得到的,将是最终的state,【版权所有】唐霜 www.tangshuang.net【未经授权禁止转载】而不是当前这个更新的值。

【版权所有】唐霜 www.tangshuang.net【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net【本文首发于唐霜的博客】

为了解决这个问题,我在写update的时【转载请注明来源】【原创内容,转载请注明出处】候,分两步走,更新值是同步的,更新视图是【原创不易,请尊重版权】【原创不易,请尊重版权】异步的。也就是说,在update之后,可【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.net以立即使用代码来获取新的值,但是视图不需本文版权归作者所有,未经授权不得转载。【版权所有,侵权必究】要马上更新,而如果视图更新了,可以通过p著作权归作者所有,禁止商业用途转载。【本文受版权保护】romise.then进一步进行操作。使【版权所有,侵权必究】【原创不易,请尊重版权】用的代码如下:

转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。
update({ name: 'tony' }).then(() => {
  console.log(this.data.name) // susan
})
console.log(this.data.name) // tony
update({ name: 'susan' })

上面这段代码看上去非常简单,但是它蕴含了本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。一定的思想。即多个update之后,它们then内部的【本文首发于唐霜的博客】原创内容,盗版必究。data是相同的。这一点极为重要,这也就实现update【版权所有,侵权必究】【未经授权禁止转载】之后,在then内部去得到更新后的视图的未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】可能性,而这个更新不单单包括当前的upd本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.netate,还包括短时间内的所有更新(当然,【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。这也带来了不可预测问题,也就是执行了一个本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。操作,可能得到非预期的效果)。

【转载请注明来源】【访问 www.tangshuang.net 获取更多精彩内容】【转载请注明来源】

那么具体怎么实现呢?其实代码非常简单:本文作者:唐霜,转载请注明出处。

【原创内容,转载请注明出处】【原创内容,转载请注明出处】未经授权,禁止复制转载。【版权所有,侵权必究】【版权所有,侵权必究】
let transactionResolves = []
let transactionPromises = []
let data = {}
let timer
function update(newData) {
  data = merge(data, newData)
  transactionPromises.push(new Promise(resolve => transactionResolves.push(resolve)))
  if (timer) clearTimeout(timer)
  timer = setTimeout(() => {
    updateView(data)
    transactionResolves.forEach(resolve => resolve())
    transactionResolves = []
    transactionPromises = []
  }, 10)
  return Promise.all(transactionPromises)
}

灰色的两个函数需要自己实现,这里只是把思转载请注明出处:www.tangshuang.net【原创内容,转载请注明出处】想表达出来。定义了两个数组,用来存放pr【作者:唐霜】原创内容,盗版必究。omise和resolve。每一次执行u本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。pdate的时候,先将promise和r原创内容,盗版必究。【原创不易,请尊重版权】esolve存放到数组中。然后用一个se【关注微信公众号:wwwtangshuangnet】【版权所有,侵权必究】tTimeout/clearTimeou【版权所有】唐霜 www.tangshuang.net著作权归作者所有,禁止商业用途转载。t来控制短时间内的重复操作。当更新视图完【作者:唐霜】【版权所有,侵权必究】成之后,执行数组中存放的所有resolv【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】e函数,这时,Promise.all就会本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。进入到resolved的状态,每一个执行著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。过的update返回的promise都会【本文受版权保护】【访问 www.tangshuang.net 获取更多精彩内容】进入then。

著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。未经授权,禁止复制转载。未经授权,禁止复制转载。

这时一个非常简陋的实现方案,由于js是单本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。线程的,因此并不存在transactio【原创不易,请尊重版权】原创内容,盗版必究。n被其他程序修改的可能。但是setTim本文版权归作者所有,未经授权不得转载。【本文受版权保护】eout会受到性能的影响,如果内部的up【本文受版权保护】本文作者:唐霜,转载请注明出处。dateView执行时间过长,就会导致下转载请注明出处:www.tangshuang.net【本文受版权保护】一个update排队。当然,这对于视觉上【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】而言并没有太大的影响。

【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】

2017-10-07 8541 ,

为价值买单,打赏一杯咖啡

本文价值85.41RMB
已有1条评论
  1. […] 把数据保存到服务端也是个话题,但相对于获取数据,是一个相对比较隔离的,但是这里又不得不讨论,因为保存数据是不可避免的。save不参与前面讨论的那几个机制,也就是说,它是独立的一个操作,你只需要提供对应的datasource id和post data,就可以把数据save到对应的url去,因此,如果你一个api设计为restful风格,其实是可以被get和save重用的,这样可以减少register的次数。save的重要机制是一个简单的事务机制,我之前写过js实现超简单setState事务机制可以在这里用上。简单的说,就是短时间内,如果执行了多次save同一个datasource的操作,那么这几个save操作其实可以合并,没有必要每次save都去请求api,而且如果多次请求,还可能导致一些错误现象的出现,比如网路震荡引起前一个request后达到,导致保存的数据反而被前一个数据覆盖。因此,保证每一个保存是所有操作最终的合并结果反而很重要。因此,save实现了这个机制。 […]