摘要:原文载于我的博客这里主要探讨一下怎么把数据请求从业务代码中抽象出来。这种操作比前面的方式显然上升了一个层面。这是非常好的准备使用观察者模式的场景。注意直接这个词,不考虑请求的意思是说未来的前端没有代码层面的,只需要拿数据,只需要拿数据。
原文载于我的博客 http://www.tangshuang.net/381...
这里主要探讨一下怎么把数据请求从业务代码中抽象出来。
传统的数据请求方式是我们在具体的业务代码,或某些特定的逻辑代码(例如redux的action)中手工写一个ajax,无论是使用最新的fetch api,还是使用axios,都是在直接构建一个请求发送器和控制请求过程。当然,这是比较容易理解的,任何人多带带看这段代码都能读懂。
但是在很多项目中,请求往往都越来越固定,总的和backend打交道的api估计不超过20个,所以我们尝试把所有的请求封装在一个services文件夹里面,形成一个独立的module,请求某个数据的时候,我们调用这个module的某个api。这种操作比前面的方式显然上升了一个层面。
但是,我们会遇到问题。当应用中的两段代码,同时使用了一个service,如果不加处理,就会导致同一个页面,同一时间,对一个backend api发出两个相同的请求。这种情况在我之前的项目中经常出现:一个页面里面有两个组件的实例。之前想到了使用cache,当一个请求发出的时候,发现参数都没变,那么直接把cache的数据返回好了,这样还可以提高数据请求的性能。然而,这完全没有解决掉问题,因为当第一次数据请求的时候,cache是没有的,两个请求还是会同时发出。后来想到,把这请求的promise缓存起来,当第一个请求发出之后,第二个请求准备发之前,先去检查cache列表中存不存在同请求的promise,如果存在,直接返回这个promise,这样,当这个promise成功的时候,两个地方的then都被触发了。
接下来,我们发现还有另外一种需求,当一个页面里面同一个组件渲染了两个实例的时候,一个实例请求到新数据,我们还希望另一个实例也可以得到这个数据,至于是否刷新界面,可以由程序来决定。这是非常好的准备使用观察者模式的场景。
观察者模式,简单的说,就是“订阅-分发”模式,观察者(订阅者)subscribe一个或多个特定订阅,当被订阅的内容发生变化时,发布者便把这些变化分发给订阅者。之所以叫观察者,是因为当观察者本身并不做任何和订阅内容相关的工作,只处于一个干自己的事,但是时时刻刻盯着自己订阅的内容,一旦收到订阅通知时,马上干对应的事。
上面的场景就是这样一种场景。我们需要独立出一个观察者,这就是datamanager,它接受来自页面内两个实例的订阅,当其中一个订阅者通过datamanager的api触发了数据请求,导致两个实例订阅的相同内容发生改变时,datamanager将新的内容同时分发给这两个实例。
看上去非常简单的逻辑,实现起来却不那么简单。索性你可以通过这里直接阅读源码来了解我是怎么实现的。
使用datamanager也很简单:
npm install --save datamanager.js
然后在你的代码中使用它:
import DataManager from "datamanager.js" const datamanager = new DataManager() datamananger.register([ ...datasources ]) // datasource请阅读文档 datamanager.subscribe("datasourceId", (data) => { // 这里可以执行ComponentB的重新渲染动作 })
在另外的代码中可以通过request来获取数据:
// ComponentA里面执行 async () => { let data = await datamanager.request("datasourceId") // 当数据回来时,上面的subscribe里的回调函数会被执行 // 用data做点事 }
datamanager提供来subscribe来进行订阅,只需要在subscribe的第二个参数中告诉datamanager,对应的datasourceId数据回来之后,自己要做什么就可以了。
回头再来看datamanager,你就发现,它不需要你告诉单次请求的url,而是把url通过datasource注册进去,它的本意就是,这个datasource可能会反复使用,因此你只需要记住它的id即可。这和我们传统的request就开始有些不同了。
request方法是完全按照传统请求返回promise的思想设计的,真正的datamanager的思想精髓,是在于它提供的get方法,当你熟悉datamanager的操作之后,开始使用get方法,而完全忘掉request方法的时候,你会发现,datamanager中完全没有数据请求的概念。它提供了一种新的思路:对于一个应用,和backend api打交道的部分被抽象出来,应用只从datamanager获取数据,而不关心它是怎么从backend拿到数据的。
对于应用而言,datamanager就在那里,你通过register注册datasource之后,就只管找它要数据就是了,要数据,给数据,要数据,给数据。后端?我不管你怎么从后端拿数据,反正我只知道数据应该在你那里。它就像一个data center,管理着前端数据。但同时,它又是observer,为实现数据在不同实例间的实时共享提供了便利。
这里可以透露一下,datamanager内部是用axios请求数据,但是对于开发者而言,不需要知道(还是需要知道axios的response结构的,如果有需要的话)。当然,这里需要说明的是,backend还是在的,只是你把backend的信息放到了datasource中,一次性注册进了datamanager。
总而言之,datamanager是对前端数据请求的一次提炼,这种提炼把前端负责的分散的数据请求代码规整化,把datasource集中管理,在代码中,不考虑请求这个动作,而是从datamanager中直接拿一个数据,拿到的是什么就是什么,不需要质疑。注意“直接”这个词,“不考虑请求”的意思是说“未来的前端没有代码层面的ajax”,只需要拿数据,只需要拿数据。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/92224.html
摘要:我们可以把取消发货单和取消订单看成一个被观察或被订阅的类实例的对象,一旦发生取消行为,我们立即通知各个观察者做出相对应的行为。装饰器模式装饰器思想,不管以前业务逻辑,甚至不去读,调用之前的接口装饰上新的数据,达到自己的目的。 前言 还是每月的目标至少写一篇文章,一晃八月份就要过去了,这个月依然没有什么产出,毫无疑问最近的状态就是不停的工作,不停的加班。所以还是把最近工作进行一个总结,首...
摘要:前言原本说接下来会专注学但是最新工作又学习了一些有意思的库於是就再写下来做个简单的入门之前我写过一篇文章这个也算是作為一个补充吧这次无非就是类似笔记把认为的一些关键点记下来有些地方还没用到就衹是描述一下代码有些自己写的有些文档写的很好就搬下 前言 原本说接下来会专注学nodejs,但是最新工作又学习了一些有意思的库,於是就再写下来做个简单的入门,之前我写过一篇文章,这个也算是作為一个补...
摘要:前言初衷以系列故事的方式展现源码逻辑,尽可能以易懂的方式讲解源码本系列文章用故事解读源码一用故事解读源码二用故事解读源码三用故事解读源码四装饰器和用故事解读源码五文章编排每篇文章分成两大段,第一大段以简单的侦探系列故事的形式讲解所涉及人物场 ================前言=================== 初衷:以系列故事的方式展现 MobX 源码逻辑,尽可能以易懂的方式...
摘要:上一篇我们讲到了关于行为树的内存优化,这一篇我们将讲述行为树的另一种优化方法基于事件的行为树。而函数负责将行为压入队列首端,节点则负责设置行为执行状态并显示调用监察函数。 上一篇我们讲到了关于行为树的内存优化,这一篇我们将讲述行为树的另一种优化方法——基于事件的行为树。 问题 在之前的行为树中,我们每帧都要从根节点开始遍历行为树,而目的仅仅是为了得到最近激活的节点,既然如此,为什么我们...
摘要:发布订阅现在每个人应该都用微信吧,一个人可以关注多个公众号,多个人可以同时关注相同的公众号。公众号每周都会更新内容,并推送给我们,把写好的文章在微信管理平台更新就好了,点击推送,就相当于发布。 什么是MVVM MVVM——Model-View-ViewModle的缩写,MVC设计模式的改进版。Model是我们应用中的数据模型,View是我们的UI层,通过ViewModle,可以把我们M...
阅读 2175·2019-08-30 15:54
阅读 1919·2019-08-30 13:49
阅读 628·2019-08-29 18:44
阅读 801·2019-08-29 18:39
阅读 1076·2019-08-29 15:40
阅读 1499·2019-08-29 12:56
阅读 3104·2019-08-26 11:39
阅读 3042·2019-08-26 11:37