From d5a6196d5b3f2b67a83b67f53d18d057e45a638c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E7=82=BD=E9=94=AE?= <397201698@qq.com> Date: Mon, 26 Jul 2021 18:35:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E7=BC=93=E5=AD=98=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/repository.ts | 5 ++ src/components/RepositoryList.tsx | 57 ++++++++++++++----- src/utils/cache/RepositorySearch.ts | 88 +++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+), 14 deletions(-) create mode 100644 src/utils/cache/RepositorySearch.ts diff --git a/src/api/repository.ts b/src/api/repository.ts index eee137b..3f6bfc9 100644 --- a/src/api/repository.ts +++ b/src/api/repository.ts @@ -5,7 +5,12 @@ export async function search (keyword:string, page:number) { url.searchParams.append('q', keyword) url.searchParams.append('page', page.toString()) const response = await fetch(url.toString(), { method: 'get' }) + const result = await response.json() + if (response.status >= 400) { + throw new Error(result.message) + } + return result as RepositorySearchResultList } diff --git a/src/components/RepositoryList.tsx b/src/components/RepositoryList.tsx index cfd41d0..b0aabd3 100644 --- a/src/components/RepositoryList.tsx +++ b/src/components/RepositoryList.tsx @@ -3,6 +3,7 @@ import { search as SearchRepository } from '../api/repository' import RepopositoryItem from './RepositoryItem' import { RepositorySearchResultItem } from '../api/api' import classes from './style/RepositoryList.module.css' +import { RepositorySearchCache } from '../utils/cache/RepositorySearch' interface RepositoryListProps { @@ -20,6 +21,8 @@ interface RepositoryListProps { const DEFAULT_PER_PAGE = 30 export default function RepositoryList (props:RepositoryListProps) { + const cache = RepositorySearchCache(props.keyword, props.max_cache_page) + /** 当前页 */ const [current_page, setCurrentPage] = useState(1) @@ -37,27 +40,53 @@ export default function RepositoryList (props:RepositoryListProps) { const [list, setList] = useState([]) - async function search (page:number) { + /** + * 调用搜索接口 + * @param {number} page 页码 + * @returns {Promise} + */ + async function search (page:number):Promise { setLoading(true) - try { - /* eslint-disable */ - var result = await SearchRepository(props.keyword, page) - } catch (err) { - setLoading(false) - return + + const cache_list = cache.read(page) + + let _total_page = 0 + + // 有缓存 + if (cache_list) { + setList(cache_list) + _total_page = cache.getTotalPage() + } else { + // 没有缓存,调用接口 + try { + /* eslint-disable */ + var result = await SearchRepository(props.keyword, page) + + } catch (err) { + console.log('fetch',err); + alert(err.message) + setLoading(false) + return + } + + _total_page = Math.ceil(result.total_count / DEFAULT_PER_PAGE) + + setList(result.items) + + cache.add(page,result.items) + cache.updateTotalPage(_total_page) } - - const _total_page = Math.ceil(result.total_count / DEFAULT_PER_PAGE) - setTotalPage(_total_page) - - setCurrentPage(page) - - setList(result.items) setPrevButtonEnable(page>1) + setNextButtonEnable(page<_total_page) + setTotalPage(_total_page) + + setCurrentPage(page) + setLoading(false) + } useEffect(() => { diff --git a/src/utils/cache/RepositorySearch.ts b/src/utils/cache/RepositorySearch.ts new file mode 100644 index 0000000..fbadd3b --- /dev/null +++ b/src/utils/cache/RepositorySearch.ts @@ -0,0 +1,88 @@ +import { RepositorySearchResultItem } from '../../api/api' + +interface CacheWrapper { + [keyword:string]:Caches +} + +interface Caches { + total_page:number + list:{[page:number]:T[]} +} + +const cache:CacheWrapper = {} + +export function RepositorySearchCache (keyword:string, max_cache_count:number) { + if (!cache[keyword]) { + cache[keyword] = { + list: [], + total_page: 0 + } + } + + const _cache = cache[keyword] + const _cache_list = _cache.list + + return { + + /** + * 读取指定页码的缓存 + * @param {number} page 页码 + * @returns {RepositorySearchResultItem[]|undefined} + */ + read (page:number):RepositorySearchResultItem[]|undefined { + return _cache_list[page] + }, + + /** + * 添加指定页码的缓存 + * @param {number} page 页码 + * @param {RepositorySearchResultItem[]} data 缓存数据 + * @returns {this} + */ + add (page:number, data:RepositorySearchResultItem[]) { + if (!_cache_list[page] && this.getCount() >= max_cache_count) { + this.remove( + parseInt(Object.keys(_cache_list).shift()!, 10) + ) + } + _cache_list[page] = data + return this + }, + + /** + * 移除指定页码的缓存 + * @param {number} page 页码 + * @returns {this} + */ + remove (page:number) { + delete _cache_list[page] + return this + }, + + /** + * 更新页码总数的缓存 + * @param {number} total 页码总数 + * @returns {this} + */ + updateTotalPage (total:number) { + _cache.total_page = total + return this + }, + + /** + * 获取页码总数缓存 + * @returns {number} + */ + getTotalPage ():number { + return _cache.total_page + }, + + /** + * 获取当前缓存总数 + * @returns {number} + */ + getCount ():number { + return Object.keys(_cache_list).length + } + } +}