请选择 进入手机版 | 继续访问电脑版
 找回密码
 立即注册
搜索

技术分享 快应用开发技巧之lock篇

0
回复
146
查看
[复制链接]

2

主题

2

帖子

20

积分

 楼主| 2019-9-16 11:28:41 显示全部楼层 |阅读模式
本帖最后由 管理员 于 2019-9-16 18:40 编辑

在编写快应用(Javascript)的过程中,会遇到许多需要加锁的场景,比如:
+ 用户重复点击提交按钮,造成反复上传表单
+ 用户连续下拉刷新,造成重复请求服务器
+ 新手引导展现后,必须三秒后才能关闭
+ ……

在js中,时下普遍的实现方式,可能是这样的:
  1. if (locked)
  2.   return

  3. locked = true

  4. //处理逻辑
  5. ...
  6. ...

  7. locked = false
复制代码
在上述代码中,只要操作速度够快,if条件是可以穿透的,因为locked还没有置为true,新的行为事件就过来了。

在翻阅了Javascript的标准内置对象以后,我发现可以使用JavaScript Array的length属性,来实锁的逻辑。

废话不多说,先上代码,lock.js:
  1. const lock = class {
  2.     constructor() {
  3.         this._lock = []
  4.     }

  5.     lock(ms = 0) {
  6.         let ok = this._lock.push(true) === 1
  7.         if (ok && ms > 0) {//自动解锁逻辑
  8.            this.timeout(ms)
  9.         }

  10.         return ok
  11.     }

  12.     unlock() {
  13.         this._lock = []
  14.     }

  15.     isLocked() {
  16.         return this._lock.length > 0
  17.     }

  18.     timeout(ms) {
  19.         let t = setTimeout(() => {
  20.             clearTimeout(t)
  21.             t = null
  22.             this.unlock()
  23.         }, ms)
  24.     }
  25. };

  26. const $ = Object.getPrototypeOf(global) || global
  27. export default $.lock = lock;
复制代码
我们现在可以将之前的示例,改造如下:
  1. const lock = new $.lock();

  2. if (!lock.lock())
  3.   return

  4. //处理逻辑
  5. ...
  6. ...

  7. lock.unlock()
复制代码
lock()方法,利用判断Array的长度来实现。即使操作再快,也不会有穿透if条件的问题。

上面代码里,用到了:
  1. Object.getPrototypeOf(global) || global
复制代码

相关知识,可以参考我的另一篇文章《快应用开发技巧之import篇》。

接下来,我们做一个更复杂的示例:
新手引导展现后,必须三秒后才能关闭。

具体实现逻辑,如下:
  1. const guideLock = new $.lock();

  2. export default {
  3.   onReady() {
  4.     this.showGuide();
  5.   },
  6.   showGuide() {   
  7.     //在展示逻辑里,设置一个锁,并在3秒后自动解锁
  8.     guideLock.lock(3000)
  9.    
  10.     ...
  11.   },
  12.   closeGuide() {
  13.     //在用户关闭界面时,如果用户提前点击,则返回
  14.     if(guideLock.isLocked()) {
  15.       ...
  16.       
  17.       return;
  18.     }
  19.    
  20.     ...
  21.   }
  22. }
复制代码

在上面的例子中,

showGuide()方法是展示新手引导的逻辑,我们在这里加了一个锁,并设置为3秒后自动解锁。

closeGuide()方法是关闭新手引导的逻辑,我们在这里判断锁的状态,如果锁还在,则不进行后面的逻辑。
以上就是利用Array特性实现的锁了,它比用变量来标记的方式更加安全,并且附带了自动解锁的功能。

更重要的是,为大家提供了一种新的思路,希望能给大家带来启发。

作者末破桑,一个碰巧写了快应用的服务端,关注快应用及快游戏,个人微信:parith。

-----------------

快应用开发技巧之import篇:https://bbs.quickapp.cn/forum.php?mod=viewthread&tid=1980
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册