前言
在需要展示大量的列表式數(shù)據(jù)時(shí)硫痰,我們都以分頁加載的方式來展示薄货,這也是行業(yè)內(nèi)慣用的方法,這種方式加速了首頁內(nèi)容的展示碍论、節(jié)約了流量資源及CPU處理資源谅猾,也優(yōu)化了用戶體驗(yàn)。
方案1
既然是分頁加載鳍悠,那么在請求時(shí)首先要提交頁碼信息税娜,所以請求接口可能是這樣的:
GET http://example.com/api/address?page_index=3&page_size=20&sort=date
返回的數(shù)據(jù)可能就是下面這樣:
{
"error_code": 1000,
"error_msg": "成功",
"extra": {
"data": [
{...},
{...},
{...},
]
},
"next_page": 3
}
方案2
在方案1的基礎(chǔ)上,加上優(yōu)化藏研,傳入的不是頁碼敬矩,而是條目的索引位置:
GET http://example.com/api/address?item_index=7&page_size=20&sort=date
返回的數(shù)據(jù)如下:
{
"error_code": 1000,
"error_msg": "成功",
"extra": {
"data": [
{...},
{...},
{...},
]
},
"next_index": 73
}
方案2只是在方案1的基礎(chǔ)上做了優(yōu)化,增加了自由度而已蠢挡。
問題
上面列舉的方案1和方案2弧岳,在面對相對靜態(tài)的數(shù)據(jù)時(shí),是沒有問題的业踏,但是禽炬,當(dāng)云端數(shù)據(jù)是動態(tài)可變時(shí)(特別當(dāng)條目可以被刪除時(shí)),會出現(xiàn)數(shù)據(jù)遺漏的問題勤家,拿方案1舉例分析:
- 假設(shè)云端數(shù)據(jù)是1腹尖、2、3伐脖、... 這樣順序排列的热幔,我們先拉取第一頁:
GET http://example.com/api/address?page_index=0&page_size=20
- 則我們得到1乐设、2、3绎巨、...近尚、20,這20條數(shù)據(jù)
- 在數(shù)據(jù)展示頁面场勤,我們刪除第一條數(shù)據(jù)肿男,然后拉取第二頁
GET http://example.com/api/address?page_index=1&page_size=20
- 因?yàn)樵贫藬?shù)據(jù)現(xiàn)在是2、3却嗡、4舶沛、...,所以第二頁數(shù)據(jù)從22開始的窗价,所以我們得到22如庭、23、24撼港、...坪它、41
發(fā)現(xiàn)了什么沒有?條目21被漏掉了帝牡,這是很明顯的錯誤往毡。
方案3
不使用頁數(shù)和條目索引這兩種方式,而是使用條目id來避開問題:
GET http://example.com/api/address?start_id=7&page_size=20
返回?cái)?shù)據(jù):
{
"error_code": 1000,
"error_msg": "成功",
"extra": {
"data": [
{...},
{...},
{...},
]
},
"next_id": 73
}
回頭看上面那個例子靶溜,第一次調(diào)用返回next_id為21开瞭,在這個頁面刪除多條數(shù)據(jù)后,下一頁請求是:
GET http://example.com/api/address?start_id=21&page_size=20
依然返回id為21那個條目開始的20條數(shù)據(jù)罩息,避開了上面那個問題嗤详。
總結(jié)
方案1只能用于數(shù)據(jù)相對靜態(tài)的場景,比如高德地圖的搜索接口瓷炮,就是用offset+size的方式來分頁加載葱色,因?yàn)椴樵兘Y(jié)果是固定的燃乍,如果數(shù)據(jù)是動態(tài)的褒翰,分頁加載過程中存在被刪除的可能,則不能使用方案1和方案2垮耳,方案3是首選烘绽,微博淋昭、twitter、Facebook這種社交平臺的開放api用的就是這種诀姚,只是更復(fù)雜响牛,用到了since_id、since_date赫段、max_id呀打、max_date等條件,感興趣的可以去看看糯笙。
實(shí)際項(xiàng)目中我的所有的分頁加載都使用方案3贬丛,請求參數(shù)有start_id,返回參數(shù)有next_id给涕,start_id 不傳或者傳-1時(shí)豺憔,返回第一頁數(shù)據(jù)以及下一頁第一條數(shù)據(jù)的id,也就是next_id够庙,這個值在請求下一頁時(shí)直接提交給start_id便可恭应。