JS实现"上次操作未完成禁止新操作"逻辑特事特办方案

 更新时间:2023年05月16日 11:27:31   作者:知名喷子  
这篇文章主要介绍了详解JS如何实现"上次操作未完成禁止新操作"的逻辑及思路,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

场景

相信很多人都遇到过类似的场景:

某一个按钮是用来发送请求的,并且需要一段时间来处理。但是用户往往会在处理期间有意或无意地点击多次,因此我们希望在上一次发出的请求处理完毕之前,不再发出新的请求。

1.初步解决方案:特事特办

“特事特办”的意思,就是每次遇到这样的场景,都特意写一段逻辑来处理:

document.addEventListener('click', (() => {
    let lock = false;
    return () => {
        if(lock) return;
        lock = true;
        console.log('clicked');
        // 为了方便测试就使用延时了
        setTimeout(() => {
            lock = false;
        }, Math.random() * 4e3)
    }
})());

2. 基于约定回调的条件式回调函数

上面的写法其实也不费事,但是这种条件限制能不能像已经被面试问烂了的“节流”和“防抖”那样,用一个函数把它包裹起来就可以达成效果呢?
问题的关键其实在于:防抖和节流需要考虑的执行条件是时间,这个条件对于所有函数而言都是一个“共同的语言”,因此才双方可以做到那样的“默契”。
而要在这种场景里实现同样的效果,双方需要刻意的约定:例如被条件执行的函数额外接受一个函数,用于在合适的时机解除条件限制。

function conditioned(callback:(release:Function,...args:any[]) => any){
    let lock = false;
      return function(...args:any[]){
        if(lock) return;
        lock = true;
        callback.call(this, () => {
              lock = false;
        }, ...args);
      }
}

 👆 为了方便描述这种约定对callback 的要求,这里使用 TS 而不是 JS。

使用的时候:

button.addEventListener('click', conditioned((release) => {
    return () => {
        console.log('clicked');
        setTimeout(() => {
            release(); // 释放 lock
        }, Math.random() * 4e3);
    }
}));

3. 基于 Promise 的条件式回调函数

如果说有什么方法能比回调函数更“优雅”、更“通用”一些,答案显然是Promise

因为上面的写法对原来的回调函数的参数进行了改写,遇到一个爱好 Ctrl + C 的初学者的话,他会疑惑复制过来的函数为什么就不工作了。

function conditioned(callback:(...args:any[]) => Promise<any>){
    let lock = false;
    return function(...args:any[]){
        if(lock) return;
        lock = true;
        try {
            await callback.call(this, ...args);
            lock = false;
        } catch(err) {
            lock = false;
            throw err;
        }
    }
}

使用方法:

button.addEventListener('click', conditioned(() => {
  return new Promise((resolve) => {
      console.log('clicked');
      setTimeout(() => {
          resolve(); // 释放 lock
      }, Math.random() * 4e3);
  });
}));

虽然乍一看,使用这个函数意味着必须把回调函数的返回值改写成 Promise,不过由于这种场景往往都是异步操作,改成 async 何乐而不为呢?

4. React hook 版

import { useRef } from 'react';
function useCondition(callback: (...args: any[]) => Promise<any>) {
  const lock = useRef(false);
  return async (...args:any[]) => {
    if(lock.current) return;
    lock.current = true;
    try{
      await callback(...args);
      lock.current = false
    } catch(error){
      lock.current = false;
      throw error;
    }
  };
}

使用方法:

<button
  onClick={useCondition(() => {
    return new Promise<void>((resolve) => {
      console.log('clicked');
      setTimeout(() => {
          resolve(); // 释放 lock
      }, Math.random() * 4e3);
    });
  })}
>测试</button>

 👆实际上没测试过,不知道行不行的,更多关于JS 上次未完成禁止新操作的资料请关注脚本之家其它相关文章!

相关文章

  • 利用JS实现加减简易计算器

    利用JS实现加减简易计算器

    这篇文章主要为大家详细介绍了如何利用JavaScript制作一个简单的网页版加减计算器,文中的示例代码讲解详细,感兴趣的可以了解一下
    2022-05-05
  • 多种js图片预加载实现方式分享

    多种js图片预加载实现方式分享

    这篇文章主要为大家详细介绍了多种js图片预加载实现方式,包括html标签或css加载图片、纯js实现预加载,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • QRCode.js二维码生成并能长按识别

    QRCode.js二维码生成并能长按识别

    这篇文章主要为大家详细介绍了QRCode.js二维码生成并能长按识别,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-10-10
  • javascript正则表达配置扩展名并实现验证

    javascript正则表达配置扩展名并实现验证

    这篇文章主要介绍了javascript正则表达配置扩展名并实现验证,文章围绕主题展开相关资料,具有以得参考价值,需要的小伙伴可以参考一下
    2022-02-02
  • JS XMLHttpRequest原理与使用方法深入详解

    JS XMLHttpRequest原理与使用方法深入详解

    这篇文章主要介绍了JS XMLHttpRequest原理与使用方法,结合实例形式深入分析了JS XMLHttpRequest相关原理、使用方法及操作注意事项,需要的朋友可以参考下
    2020-04-04
  • JavaScript编写点击查看大图的页面半透明遮罩层效果实例

    JavaScript编写点击查看大图的页面半透明遮罩层效果实例

    这篇文章主要介绍了JavaScript制作点击查看大图的页面遮罩层效果实例,透明部分这里使用的是CSS3的rgba,兼容性还是过得去的,需要的朋友可以参考下
    2016-05-05
  • js 图片懒加载的实现

    js 图片懒加载的实现

    这篇文章主要介绍了js 图片懒加载的实现,帮助大家更好的优化自身网页,提高网页响应速度,感兴趣的朋友可以了解下
    2020-10-10
  • 一个关于javascript匿名函数的问题分析

    一个关于javascript匿名函数的问题分析

    一个关于javascript匿名函数的问题分析,学习js的朋友可以参考下
    2012-03-03
  • JS隐藏号码中间4位代码实例

    JS隐藏号码中间4位代码实例

    这篇文章主要介绍了JS隐藏号码中间4位,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • 小程序如何获取多个formId实现详解

    小程序如何获取多个formId实现详解

    这篇文章主要介绍了小程序如何获取多个formId实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09

最新评论