转载

野狗(Wilddog)的实时同步机制

当我们谈论自己的产品Wilddog时,其实大多数时间我们在谈同步机制。

工具决定高度

工程的东西往往具有一个特点,后人不断站在前人的肩膀上,以前人的工作成果作为起点。

人类的进化也符合这个特征

野狗(Wilddog)的实时同步机制

人类的老祖宗进化成人类的一个最重要的里程碑是使用火--使用火,可以吃熟食。熟食更利于消化,吃的更少就可以提供足够的营养,食物负担减少,因此老祖宗门有了更多的时间去思考”猿生“的意义,有更多的时间制作效率更高的工具,也有了更多的营养发育大脑,因此才有了人类文明的起飞。要注意,这一切都源于火的使用。当然今天的主题并不是生物进化,关于老祖宗的话题就此结束,只留一个结论: 工具决定高度!

说到这里,有很多工程师不屑于这个结论:老子不需要先进的工具,只靠手速就可以战胜88%的工程师。我想说的是汽车在刚刚发明的时候一定没有人跑的快,但汽车性能的发展是线性的,而人类体能的发展是偶然性的!一旦汽车超过人,人类就被远远的抛在后面,永远没有机会。经过不断的训练,你可以把自己的百米成绩提高10%,然而只需要借助工具,不需要任何努力,这个数值可能是1000% 。

野狗(Wilddog)的实时同步机制

工具决定高度有两层原因:

  • 第一层:工具可以简化操作
  • 第二层:工具可以简化思考

就Web开发来说,一个工具帮你节约时间体现在帮你搞定兼容性,把原生的“能用的”API封装成“好用的”API,没错,我说的是JQuery。Jquery的优势体现在第一个层次,却没有体现在第二个层次,你还是思考DOM如何变化,监听哪些事件等一系列繁琐的事情。

我拿来与JQuery对比的工具是:AngularJS,React这类提供数据绑定的框架。当写一个逻辑复杂的页面,操作DOM变成了一件非常乏味而且恐怖的事情,这个时候你会问:TM为什么要操作DOM,为什么要监听事件?是的,其实你并不需要,或者说不需直接操作DOM。数据绑定帮我们做了数据(模型,状态)->DOM的事情,因此你只需要操作数据模型。操作数据比操作DOM要简单的多。

大脑并不是一个无限的容器,装下了DOM操作就装不下上层的业务逻辑。当你不必为DOM操作而烦恼的时候,就可以思考更多高层的东西。你并不关心DOM操作,网络传输,你只关心实现功能,也就是业务逻辑。在业务逻辑之外思考的越少越好,好的工具就是给你一个思维的框架,简化你的思维模型。

当然,作为开发者,你也许不会为减少这一点点脑力负担有多么了不起,就像原始人不会想到减少一点点食物负担对于世界有多少影响。

所以,我们需要更好的

营养

工具。

数据同步优于数据传输

数据绑定优于DOM操作。所以Angular,React 都提供数据绑定机制。

同样,在实时数据传输这件事情上对比两种方式:

  • 直接传输
  • 数据同步

直接传输是指将数据从一端直接发给另外一端。而数据同步发生在两个数据源之间,有一套算法机制保证其完全一致。传输仅仅是一个管道,而同步是管道加两端的数据池。

Socket.io 这类工具帮开发者解决了兼容性,甚至提供了服务端,的确简化了操作。但跟Jquery一样,没有简化思考。当你开发时,你需要考虑当前客户端是否在线,对端是否在线这样的问题。所以你的思维模型是 (服务端数据,目标客户端数据,本地数据,业务逻辑):

野狗(Wilddog)的实时同步机制

而如果提供同步机制,你的思维模型就只是(本地数据,业务逻辑):

野狗(Wilddog)的实时同步机制

由于本地有数据源,开发者只需要关心对本地数据源的修改,本地数据源到服务端,到后端的一系列事情都由同步机制来解决。

由此我们看出同步相对于数据传输的最大优势--简化开发模型。

Wilddog的同步机制通过以下方面简化开发模型:

  • 传输过程透明
  • 在线与离线逻辑统一
  • 事件模型统一

传输过程透明与在线离线逻辑统一

这个很好理解,Wilddog的数据操作API是 set update remove push

这些API的语义是 修改本地存储数据 (顺便同步到云端,如果当前不在线,就等在线后再说)。API是面向本地数据修改的,传输的过程完全封装。

而数据的查询 on , once 在离线后也能够正常使用,本地数据操作能够正常触发 value child_added child_removed child_moved child_changed 事件。对于开发者来说,即使在离线情况下,所有的API都能够工作正常,所有的事件都能够正常触发。大多数情况下并不需要考虑在线与离线,而需要考虑的场景下,Wilddog也提供了查询当前在线状态的方法。

ref.on('child_changed',function(snapshot){       //即使在离线状态下也会触发     console.log(snapshot.val()) }) ref.set('hello',function(err){       //数据同步完成才会触发     console.log("sync complete") }) 

如果你不怎么关心这条数据是否真的被写到服务端,而只是关心这条数据这条数据在本地产生的影响 set 的回调可以不用。如果你关心数据真正被写到服务端,可以通过这个回调函数来处理。

事件模型统一

同步的另外一个优势是统一事件模型。如果你需要维护一个数组,将数组中的所有数据打印出来,一般你需要这么做

//可能存在某些初始数据 var d = init()   //监听新增的数据 d.forEach(function(data){     console.log(data) }) socket.on('message',function(data){       d.push(data);     console.log(data) }) 

但是这段代码足以杀死处女座了,为什么对d的维护需要两段不同的逻辑:初始化和监听后续变化? 为什么打印要调用2次?这段代码可以优化的很优雅,问题是需要时间。这段代码是我凭第一感觉写出来的,相信大多数工程师也会有类似的表现。

那么看一下同步机制下的事件如何拯救处女座:

ref.on('child_added',function(snapshot){      cosole.log(snap.val()); }) 

没错,就这么简单,即使是已经存在的数据依然会触发这个回调,事件机制就这样统一了。

数据同步优于数据传输

Ending

工具决定你的思维模型,Wilddog的同步机制简化了思维模型,让你聚焦到业务逻辑。AND-处女座程序员的拯救者 :-)

原文  http://blog.jackxy.com/2016/04/01/wilddog-sync/
正文到此结束
Loading...