|
本帖最后由 管理员 于 2019-9-16 18:40 编辑
在编写快应用(Javascript)的过程中,会遇到许多需要加锁的场景,比如:
+ 用户重复点击提交按钮,造成反复上传表单
+ 用户连续下拉刷新,造成重复请求服务器
+ 新手引导展现后,必须三秒后才能关闭
+ ……
在js中,时下普遍的实现方式,可能是这样的:- if (locked)
- return
-
- locked = true
-
- //处理逻辑
- ...
- ...
-
- locked = false
复制代码 在上述代码中,只要操作速度够快,if条件是可以穿透的,因为locked还没有置为true,新的行为事件就过来了。
在翻阅了Javascript的标准内置对象以后,我发现可以使用JavaScript Array的length属性,来实锁的逻辑。
废话不多说,先上代码,lock.js:- const lock = class {
- constructor() {
- this._lock = []
- }
-
- lock(ms = 0) {
- let ok = this._lock.push(true) === 1
- if (ok && ms > 0) {//自动解锁逻辑
- this.timeout(ms)
- }
-
- return ok
- }
-
- unlock() {
- this._lock = []
- }
-
- isLocked() {
- return this._lock.length > 0
- }
-
- timeout(ms) {
- let t = setTimeout(() => {
- clearTimeout(t)
- t = null
- this.unlock()
- }, ms)
- }
- };
-
- const $ = Object.getPrototypeOf(global) || global
- export default $.lock = lock;
复制代码 我们现在可以将之前的示例,改造如下:
- const lock = new $.lock();
-
- if (!lock.lock())
- return
-
- //处理逻辑
- ...
- ...
-
- lock.unlock()
复制代码 lock()方法,利用判断Array的长度来实现。即使操作再快,也不会有穿透if条件的问题。
上面代码里,用到了:
- Object.getPrototypeOf(global) || global
复制代码
相关知识,可以参考我的另一篇文章《快应用开发技巧之import篇》。
接下来,我们做一个更复杂的示例:
具体实现逻辑,如下:
- const guideLock = new $.lock();
-
- export default {
- onReady() {
- this.showGuide();
- },
- showGuide() {
- //在展示逻辑里,设置一个锁,并在3秒后自动解锁
- guideLock.lock(3000)
-
- ...
- },
- closeGuide() {
- //在用户关闭界面时,如果用户提前点击,则返回
- if(guideLock.isLocked()) {
- ...
-
- return;
- }
-
- ...
- }
- }
复制代码
在上面的例子中,
showGuide()方法是展示新手引导的逻辑,我们在这里加了一个锁,并设置为3秒后自动解锁。
closeGuide()方法是关闭新手引导的逻辑,我们在这里判断锁的状态,如果锁还在,则不进行后面的逻辑。
以上就是利用Array特性实现的锁了,它比用变量来标记的方式更加安全,并且附带了自动解锁的功能。
更重要的是,为大家提供了一种新的思路,希望能给大家带来启发。
作者末破桑,一个碰巧写了快应用的服务端,关注快应用及快游戏,个人微信:parith。
-----------------
快应用开发技巧之import篇:https://bbs.quickapp.cn/forum.php?mod=viewthread&tid=1980
|
|