实现缓存功能

This commit is contained in:
周炽键 2021-07-26 18:35:38 +08:00
parent 78addb6d96
commit d5a6196d5b
3 changed files with 136 additions and 14 deletions

View File

@ -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
}

View File

@ -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<RepositorySearchResultItem[]>([])
async function search (page:number) {
/**
*
* @param {number} page
* @returns {Promise<void>}
*/
async function search (page:number):Promise<void> {
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(() => {

88
src/utils/cache/RepositorySearch.ts vendored Normal file
View File

@ -0,0 +1,88 @@
import { RepositorySearchResultItem } from '../../api/api'
interface CacheWrapper<T> {
[keyword:string]:Caches<T>
}
interface Caches<T> {
total_page:number
list:{[page:number]:T[]}
}
const cache:CacheWrapper<RepositorySearchResultItem> = {}
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
}
}
}