摘要:原文載于我的博客這里主要探討一下怎么把數據請求從業務代碼中抽象出來。這種操作比前面的方式顯然上升了一個層面。這是非常好的準備使用觀察者模式的場景。注意直接這個詞,不考慮請求的意思是說未來的前端沒有代碼層面的,只需要拿數據,只需要拿數據。
原文載于我的博客 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”,只需要拿數據,只需要拿數據。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92224.html
摘要:我們可以把取消發貨單和取消訂單看成一個被觀察或被訂閱的類實例的對象,一旦發生取消行為,我們立即通知各個觀察者做出相對應的行為。裝飾器模式裝飾器思想,不管以前業務邏輯,甚至不去讀,調用之前的接口裝飾上新的數據,達到自己的目的。 前言 還是每月的目標至少寫一篇文章,一晃八月份就要過去了,這個月依然沒有什么產出,毫無疑問最近的狀態就是不停的工作,不停的加班。所以還是把最近工作進行一個總結,首...
摘要:前言原本說接下來會專注學但是最新工作又學習了一些有意思的庫於是就再寫下來做個簡單的入門之前我寫過一篇文章這個也算是作為一個補充吧這次無非就是類似筆記把認為的一些關鍵點記下來有些地方還沒用到就衹是描述一下代碼有些自己寫的有些文檔寫的很好就搬下 前言 原本說接下來會專注學nodejs,但是最新工作又學習了一些有意思的庫,於是就再寫下來做個簡單的入門,之前我寫過一篇文章,這個也算是作為一個補...
摘要:前言初衷以系列故事的方式展現源碼邏輯,盡可能以易懂的方式講解源碼本系列文章用故事解讀源碼一用故事解讀源碼二用故事解讀源碼三用故事解讀源碼四裝飾器和用故事解讀源碼五文章編排每篇文章分成兩大段,第一大段以簡單的偵探系列故事的形式講解所涉及人物場 ================前言=================== 初衷:以系列故事的方式展現 MobX 源碼邏輯,盡可能以易懂的方式...
摘要:上一篇我們講到了關于行為樹的內存優化,這一篇我們將講述行為樹的另一種優化方法基于事件的行為樹。而函數負責將行為壓入隊列首端,節點則負責設置行為執行狀態并顯示調用監察函數。 上一篇我們講到了關于行為樹的內存優化,這一篇我們將講述行為樹的另一種優化方法——基于事件的行為樹。 問題 在之前的行為樹中,我們每幀都要從根節點開始遍歷行為樹,而目的僅僅是為了得到最近激活的節點,既然如此,為什么我們...
摘要:發布訂閱現在每個人應該都用微信吧,一個人可以關注多個公眾號,多個人可以同時關注相同的公眾號。公眾號每周都會更新內容,并推送給我們,把寫好的文章在微信管理平臺更新就好了,點擊推送,就相當于發布。 什么是MVVM MVVM——Model-View-ViewModle的縮寫,MVC設計模式的改進版。Model是我們應用中的數據模型,View是我們的UI層,通過ViewModle,可以把我們M...
閱讀 2211·2019-08-30 15:54
閱讀 1947·2019-08-30 13:49
閱讀 665·2019-08-29 18:44
閱讀 824·2019-08-29 18:39
閱讀 1104·2019-08-29 15:40
閱讀 1524·2019-08-29 12:56
閱讀 3134·2019-08-26 11:39
閱讀 3094·2019-08-26 11:37