Wednesday, March 27, 2019

NodeJS简介


Axios

Axios是一个基于Promise的 HTTP 库,可以用在浏览器和node.js 中

Ref
Axios例子
与Ajax的区别

Saturday, March 23, 2019

xposed

http://www.oneplusbbs.com/thread-4037966-1.html
https://repo.xposed.info/module-overview
https://kuaibao.qq.com/s/20180417G1VSM600?refer=spider
https://www.jianshu.com/p/393f5e51716e

Thursday, March 21, 2019

NodeJS的debounce和throttle区别

axios是一个NodeJS的库,它含有两个函数来避免发过多request到后端,从而提高相应。

debounce防抖动:把触发非常频繁的事件(比如按键)合并成一次执行。若此时间段内,只有一个事件,它会在时钟的末尾执行。例子:autocomplete,resize等需要等待用户按键结束的用例。
throttle节流:保证每 X 毫秒恒定的执行次数。例子:无限滚动,没有事件或者事件带连续性的用例。

区别就是,防抖动是时间做阈值,而throttle就是用数量做阈值。例如automplete用防抖动实现,如果用户输入速度快于阈值,就不会发request到后端,只有当某次输入超过阈值,也就是这段时间内只有一个输入,才会发到后端。也可以看出防抖动属于延迟执行,也就是等待时间阈值后才实际执行。而节流是立即执行,但该时间段内其他的不再执行。还是用autocomplete的例子,若用节流实现的话,即使用户输入快于时间阈值,request还是会发,只发一个。

cancelToken: debounce还和cancelToken一起用,表示若发到后端的request已经发出,而用户现在输入,前端即使受到response也不再处理。若无此,可能输入新字母后还会出现前一次结果。甚至用户跳转到新页面了,网站当收到response后悔跳转到旧页面,用户会感到非常奇怪。

解释
官网定义
区别

Sunday, March 10, 2019

Guava Cache简介

Guava Cache是一个全内存的本地缓存实现,它提供了线程安全的实现机制。整体上来说Guava cache 是本地缓存的不二之选,简单易用,性能好。相对于distributed cache而言

http://www.cnblogs.com/peida/p/Guava_Cache.html
https://www.jianshu.com/p/afe7b2dccee0

Tuesday, March 5, 2019

流式分页 Pagination

传统分页和流式分页

流式分页应用场景:

通过滚动/上拉/点击等方式加载新一页
无页码
无上/下页按钮
不可跳转至指定页面
pc端和移动端均有使用

实现:

前端实现:后端返回全部结果,前端做分页

后端实现:

用offset和limit来实现(mysql)

优化:

当前页数据(及其之前)若有删除,由于计算问题total/limit*offset,数据整体上移(变少),指针相对下移,会出现数据缺失。
当前页数据(及其之前)若有增加,由于计算问题total/limit*offset,数据整体下移(变多),指针相对上移,会出现数据重复。

方案:

1. 后端方案,缓存数据
2. 后端方案,用cursor记录最后一个ID。这叫游标式分页。DynamoDB采用这个方案。pagination token带有过期时间戳。
3. 前端方案,一次性发所有Id,缓存到前端。
4. 前端方案,客户端保留已浏览数据,手动去重。不能避免数据缺失。

游标式分页

这个方案避免了数据缺失和重复,但有适用范围。它仅能用于追加式的单一排序。这要求
1. 单一排序:这个顺序是固定的,而且可以快速定位到这个ID。
2. 追加式:只能添加和删除一行,不能更新某些域。更新它们若影响排序的话,就涉及数据快照概念。若第一页分页请求产生时(方案一)生成时间戳,这个时间戳对应整套数据的快照,若某些域在这个时间戳之后更新(可以按行来添加lastUpdateTime),按照设计,应该显示旧值。这要求每个域所有更新都要有历史记录。此解决方案有利有弊:可以避免数据重复出现,但是新数据会不显示。

* 快照模式:用lastUpdatedTimestamp
* 若要实现scroll down时候,新加入的entries也显示,这不属于快照模式,可以用timestamp的UUID, uuid > last-entry-uuid就可以,缺点是符号条件的entry只能按插入时间顺序排序而不能按其他条件排序

MongoDB的游标式实现

Request:
// Query the first page.
  let result = await MongoPaging.find(db.collection('myobjects'), {
    limit: 2
  });
  console.log(result);

  // Query next page.
  result = MongoPaging.find(db.collection('myobjects'), {
    limit: 2,
    next: result.next // This queries the next page
  });
  console.log(result);
}

Response:
page 1 { results:
   [ { _id: 580fd16aca2a6b271562d8bb, counter: 4 },
     { _id: 580fd16aca2a6b271562d8ba, counter: 3 } ],
  next: 'eyIkb2lkIjoiNTgwZmQxNmFjYTJhNmIyNzE1NjJkOGJhIn0',
  hasNext: true }
page 2 { results:
   [ { _id: 580fd16aca2a6b271562d8b9, counter: 2 },
     { _id: 580fd16aca2a6b271562d8b8, counter: 1 } ],
  previous: 'eyIkb2lkIjoiNTgwZmQxNmFjYTJhNmIyNzE1NjJkOGI5In0',
  next: 'eyIkb2lkIjoiNTgwZmQxNmFjYTJhNmIyNzE1NjJkOGI4In0',
  hasNext: false }

Request中的limit的返回结果的大小,next上改页结果的最后一项的id,也就是下一页结果需要从这个项目后开始查找。
Response中的token是 {_id: 123} 的base64 encode. 比如page 1的next就是第二个(最后一个)id的encode。hasNext的设计可以让客户更清晰地知道是否有下一页,当然也可以用next=''来替代。

在有些设计中,token加入timestamp, {_id: 123, timestamp: 2019-06-21 12:23:11},设一个SLA为24小时,也就是下一个翻页请求在SLA内完成,这样可以减少不必要的请求。


Ref
[1] https://aotu.io/notes/2017/06/27/infinite-scrolling/index.html
[2] MongoDB实现
[3] 游标式分页的优势