101. 合并相同的API请求

中等难度  -通过 / -执行

⚠️ This questions is updated on Oct 22, 2022 which has breaking changes on test specs. Thanks to @Qzlt4LK.

假设我们有个getAPI()方法来调取API。

const getAPI =  <T>(
  path: string, 
  config: SomeConfig
): Promise<T> => { ... }

const list1 = await getAPI('/list', { keyword: 'bfe'})
const list2 = await getAPI('/list', { keyword: 'dev'})

这本来运行地很好。直到页面UI变得如此复杂,以至于相同的API在极短的时间内被调用了多次。

你想要基于如下的假设避免没必要的API请求。

在1000ms以内的GET API的response几乎肯定是一样的

所以相同的GET API在1000ms即使调用多次也会返回相同的内容。相同的意思是,pathconfig都是 deeply equal

你实现了如下的 createGetAPIWithMerging(getAPI)方法。


const getAPIWithMerging = createGetAPIWithMerging(getAPI)

getAPIWithMerging('/list', { keyword: 'bfe'}).then(...)  
// 第1次调用。getAPI被触发。

getAPIWithMerging('/list', { keyword: 'bfe'}).then(...) 
// 第2次调用和第1次是相同的
// 所以 getAPI 被没有被触发
// 被合并到了第1次调用中

getAPIWithMerging('/list', { keyword: 'dev'}).then(...)
// 第3次调用是不同的参数,所以getAPI被触发

// 1000ms 过后
getAPIWithMerging('/list', {keyword: 'bfe'}).then(...)
// 第4次调用和第1次相同
// 不过已经过了1000ms,getAPI还是被触发

请注意内存泄漏!

你的缓存机制需要设置上限。该问题中,请设置为最多5条缓存记录。意味着:

getAPIWithMerging('/list1', { keyword: 'bfe'}).then(...) 
// 第1次调用,触发callAPI(),添加1条缓存记录
getAPIWithMerging('/list2', { keyword: 'bfe'}).then(...) 
// 第2次调用,触发callAPI(),添加1条缓存记录
getAPIWithMerging('/list3', { keyword: 'bfe'}).then(...) 
// 第3次调用,触发callAPI(),添加1条缓存记录
getAPIWithMerging('/list4', { keyword: 'bfe'}).then(...) 
// 第4次调用,触发callAPI(),添加1条缓存记录
getAPIWithMerging('/list5', { keyword: 'bfe'}).then(...) 
// 第5次调用,触发callAPI(),添加1条缓存记录

getAPIWithMerging('/list6', { keyword: 'bfe'}).then(...) 
// 第6次调用,触发callAPI(),添加1条缓存记录
// 第1次调用的缓存记录被删除

getAPIWithMerging('/list1', { keyword: 'bfe'}).then(...) 
// 和第1次调用相同,但是没有缓存的数据
// 所以新的缓存记录被添加

clear()

为了测试,请提供上述方法来清楚所有缓存。调用方式如下

getAPIWithMerging.clearCache()

一边解释一边码字。

(1)
(45)