摘要:原文載于我的博客這里主要探討一下怎么把數(shù)據(jù)請求從業(yè)務(wù)代碼中抽象出來。這種操作比前面的方式顯然上升了一個層面。這是非常好的準備使用觀察者模式的場景。注意直接這個詞,不考慮請求的意思是說未來的前端沒有代碼層面的,只需要拿數(shù)據(jù),只需要拿數(shù)據(jù)。
原文載于我的博客 http://www.tangshuang.net/381...
這里主要探討一下怎么把數(shù)據(jù)請求從業(yè)務(wù)代碼中抽象出來。
傳統(tǒng)的數(shù)據(jù)請求方式是我們在具體的業(yè)務(wù)代碼,或某些特定的邏輯代碼(例如redux的action)中手工寫一個ajax,無論是使用最新的fetch api,還是使用axios,都是在直接構(gòu)建一個請求發(fā)送器和控制請求過程。當然,這是比較容易理解的,任何人多帶帶看這段代碼都能讀懂。
但是在很多項目中,請求往往都越來越固定,總的和backend打交道的api估計不超過20個,所以我們嘗試把所有的請求封裝在一個services文件夾里面,形成一個獨立的module,請求某個數(shù)據(jù)的時候,我們調(diào)用這個module的某個api。這種操作比前面的方式顯然上升了一個層面。
但是,我們會遇到問題。當應用中的兩段代碼,同時使用了一個service,如果不加處理,就會導致同一個頁面,同一時間,對一個backend api發(fā)出兩個相同的請求。這種情況在我之前的項目中經(jīng)常出現(xiàn):一個頁面里面有兩個組件的實例。之前想到了使用cache,當一個請求發(fā)出的時候,發(fā)現(xiàn)參數(shù)都沒變,那么直接把cache的數(shù)據(jù)返回好了,這樣還可以提高數(shù)據(jù)請求的性能。然而,這完全沒有解決掉問題,因為當?shù)谝淮螖?shù)據(jù)請求的時候,cache是沒有的,兩個請求還是會同時發(fā)出。后來想到,把這請求的promise緩存起來,當?shù)谝粋€請求發(fā)出之后,第二個請求準備發(fā)之前,先去檢查cache列表中存不存在同請求的promise,如果存在,直接返回這個promise,這樣,當這個promise成功的時候,兩個地方的then都被觸發(fā)了。
接下來,我們發(fā)現(xiàn)還有另外一種需求,當一個頁面里面同一個組件渲染了兩個實例的時候,一個實例請求到新數(shù)據(jù),我們還希望另一個實例也可以得到這個數(shù)據(jù),至于是否刷新界面,可以由程序來決定。這是非常好的準備使用觀察者模式的場景。
觀察者模式,簡單的說,就是“訂閱-分發(fā)”模式,觀察者(訂閱者)subscribe一個或多個特定訂閱,當被訂閱的內(nèi)容發(fā)生變化時,發(fā)布者便把這些變化分發(fā)給訂閱者。之所以叫觀察者,是因為當觀察者本身并不做任何和訂閱內(nèi)容相關(guān)的工作,只處于一個干自己的事,但是時時刻刻盯著自己訂閱的內(nèi)容,一旦收到訂閱通知時,馬上干對應的事。
上面的場景就是這樣一種場景。我們需要獨立出一個觀察者,這就是datamanager,它接受來自頁面內(nèi)兩個實例的訂閱,當其中一個訂閱者通過datamanager的api觸發(fā)了數(shù)據(jù)請求,導致兩個實例訂閱的相同內(nèi)容發(fā)生改變時,datamanager將新的內(nèi)容同時分發(fā)給這兩個實例。
看上去非常簡單的邏輯,實現(xiàn)起來卻不那么簡單。索性你可以通過這里直接閱讀源碼來了解我是怎么實現(xiàn)的。
使用datamanager也很簡單:
npm install --save datamanager.js
然后在你的代碼中使用它:
import DataManager from "datamanager.js" const datamanager = new DataManager() datamananger.register([ ...datasources ]) // datasource請閱讀文檔 datamanager.subscribe("datasourceId", (data) => { // 這里可以執(zhí)行ComponentB的重新渲染動作 })
在另外的代碼中可以通過request來獲取數(shù)據(jù):
// ComponentA里面執(zhí)行 async () => { let data = await datamanager.request("datasourceId") // 當數(shù)據(jù)回來時,上面的subscribe里的回調(diào)函數(shù)會被執(zhí)行 // 用data做點事 }
datamanager提供來subscribe來進行訂閱,只需要在subscribe的第二個參數(shù)中告訴datamanager,對應的datasourceId數(shù)據(jù)回來之后,自己要做什么就可以了。
回頭再來看datamanager,你就發(fā)現(xiàn),它不需要你告訴單次請求的url,而是把url通過datasource注冊進去,它的本意就是,這個datasource可能會反復使用,因此你只需要記住它的id即可。這和我們傳統(tǒng)的request就開始有些不同了。
request方法是完全按照傳統(tǒng)請求返回promise的思想設(shè)計的,真正的datamanager的思想精髓,是在于它提供的get方法,當你熟悉datamanager的操作之后,開始使用get方法,而完全忘掉request方法的時候,你會發(fā)現(xiàn),datamanager中完全沒有數(shù)據(jù)請求的概念。它提供了一種新的思路:對于一個應用,和backend api打交道的部分被抽象出來,應用只從datamanager獲取數(shù)據(jù),而不關(guān)心它是怎么從backend拿到數(shù)據(jù)的。
對于應用而言,datamanager就在那里,你通過register注冊datasource之后,就只管找它要數(shù)據(jù)就是了,要數(shù)據(jù),給數(shù)據(jù),要數(shù)據(jù),給數(shù)據(jù)。后端?我不管你怎么從后端拿數(shù)據(jù),反正我只知道數(shù)據(jù)應該在你那里。它就像一個data center,管理著前端數(shù)據(jù)。但同時,它又是observer,為實現(xiàn)數(shù)據(jù)在不同實例間的實時共享提供了便利。
這里可以透露一下,datamanager內(nèi)部是用axios請求數(shù)據(jù),但是對于開發(fā)者而言,不需要知道(還是需要知道axios的response結(jié)構(gòu)的,如果有需要的話)。當然,這里需要說明的是,backend還是在的,只是你把backend的信息放到了datasource中,一次性注冊進了datamanager。
總而言之,datamanager是對前端數(shù)據(jù)請求的一次提煉,這種提煉把前端負責的分散的數(shù)據(jù)請求代碼規(guī)整化,把datasource集中管理,在代碼中,不考慮請求這個動作,而是從datamanager中直接拿一個數(shù)據(jù),拿到的是什么就是什么,不需要質(zhì)疑。注意“直接”這個詞,“不考慮請求”的意思是說“未來的前端沒有代碼層面的ajax”,只需要拿數(shù)據(jù),只需要拿數(shù)據(jù)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/92224.html
摘要:我們可以把取消發(fā)貨單和取消訂單看成一個被觀察或被訂閱的類實例的對象,一旦發(fā)生取消行為,我們立即通知各個觀察者做出相對應的行為。裝飾器模式裝飾器思想,不管以前業(yè)務(wù)邏輯,甚至不去讀,調(diào)用之前的接口裝飾上新的數(shù)據(jù),達到自己的目的。 前言 還是每月的目標至少寫一篇文章,一晃八月份就要過去了,這個月依然沒有什么產(chǎn)出,毫無疑問最近的狀態(tài)就是不停的工作,不停的加班。所以還是把最近工作進行一個總結(jié),首...
摘要:前言原本說接下來會專注學但是最新工作又學習了一些有意思的庫於是就再寫下來做個簡單的入門之前我寫過一篇文章這個也算是作為一個補充吧這次無非就是類似筆記把認為的一些關(guān)鍵點記下來有些地方還沒用到就衹是描述一下代碼有些自己寫的有些文檔寫的很好就搬下 前言 原本說接下來會專注學nodejs,但是最新工作又學習了一些有意思的庫,於是就再寫下來做個簡單的入門,之前我寫過一篇文章,這個也算是作為一個補...
摘要:前言初衷以系列故事的方式展現(xiàn)源碼邏輯,盡可能以易懂的方式講解源碼本系列文章用故事解讀源碼一用故事解讀源碼二用故事解讀源碼三用故事解讀源碼四裝飾器和用故事解讀源碼五文章編排每篇文章分成兩大段,第一大段以簡單的偵探系列故事的形式講解所涉及人物場 ================前言=================== 初衷:以系列故事的方式展現(xiàn) MobX 源碼邏輯,盡可能以易懂的方式...
摘要:上一篇我們講到了關(guān)于行為樹的內(nèi)存優(yōu)化,這一篇我們將講述行為樹的另一種優(yōu)化方法基于事件的行為樹。而函數(shù)負責將行為壓入隊列首端,節(jié)點則負責設(shè)置行為執(zhí)行狀態(tài)并顯示調(diào)用監(jiān)察函數(shù)。 上一篇我們講到了關(guān)于行為樹的內(nèi)存優(yōu)化,這一篇我們將講述行為樹的另一種優(yōu)化方法——基于事件的行為樹。 問題 在之前的行為樹中,我們每幀都要從根節(jié)點開始遍歷行為樹,而目的僅僅是為了得到最近激活的節(jié)點,既然如此,為什么我們...
摘要:發(fā)布訂閱現(xiàn)在每個人應該都用微信吧,一個人可以關(guān)注多個公眾號,多個人可以同時關(guān)注相同的公眾號。公眾號每周都會更新內(nèi)容,并推送給我們,把寫好的文章在微信管理平臺更新就好了,點擊推送,就相當于發(fā)布。 什么是MVVM MVVM——Model-View-ViewModle的縮寫,MVC設(shè)計模式的改進版。Model是我們應用中的數(shù)據(jù)模型,View是我們的UI層,通過ViewModle,可以把我們M...
閱讀 2325·2019-08-30 15:54
閱讀 2047·2019-08-30 13:49
閱讀 728·2019-08-29 18:44
閱讀 884·2019-08-29 18:39
閱讀 1171·2019-08-29 15:40
閱讀 1589·2019-08-29 12:56
閱讀 3216·2019-08-26 11:39
閱讀 3160·2019-08-26 11:37