首页 > 其他分享 >动态添加的Promise按顺序执行

动态添加的Promise按顺序执行

时间:2023-12-29 16:13:09浏览次数:36  
标签:eventArr 顺序 isRunning 动画 timerArr 添加 let Promise document

原文链接:https://www.cnblogs.com/yalong/p/17935043.html

动态添加的Promise异步事件按顺序执行

需求描述

用户点击一次页面上的一个按钮,就播放一个动画, 如果点击n次就触发n次动画;
在播放动画的同时,如果再点击按钮,那么会把n的次数累加,动画播放也增加对应的次数;
同时支持在动画队列没播放完的时候,可以手动取消后续的动画播放

实现的效果展示

定时器设置为2秒,可以看到不管点击多少次,都是2秒后触发一次,期间可以取消,取消后再点击还是之前的逻辑
因为视频转为gif之后,显示播放的慢了,看打印的时间其实还是2秒的间隔
可以自行复制下面的代码,运行看下效果

代码实现

下面代码中 用setTimeout模拟异步,具体的动画可以放在里面,外面用Promise包裹

<html>
    <style>
        .container {
            border:  1px solid red;
            min-height: 100px;
        }
    </style>
    <body>
        <button id="btn">点我触发事件</button>
        <button id="btn2">点我取消事件</button>
        <button id="btn3">清屏</button>
        <ul class="container">
        </ul>
    </body>
    <script>
        let eventArr = []; //异步事件队列
        let isRunning = false; // 是否正在执行异步事件
        let timerArr = []; // 定时器的数组 用来清除定时器用

        let p = function () {
            return new Promise((resolve, reject) => {
                let t = setTimeout(() => {
                    let d = new Date()
                    let node = document.createElement('li');
                    node.innerHTML = `${eventArr.length + 1} - ${d}`
                    document.querySelector('.container').appendChild(node);
                    resolve(d);
                }, 2000);
                timerArr.push(t);
            });
        }

        document.querySelector('#btn').addEventListener('click', async function(){
            eventArr.push(p);
            if (!isRunning) {
                runner();
            }
        });

        // 取消事件
        document.querySelector('#btn2').addEventListener('click', async function(){
            eventArr = [];
            timerArr.forEach(item => {
                clearTimeout(item);
            });
            timerArr = [];
            isRunning = false;
        });

        // 清屏
        document.querySelector('#btn3').addEventListener('click', async function(){
            document.querySelector('.container').innerHTML = ''
        });

        async function runner (){
            if (eventArr.length) {
                isRunning = true;
                let temp = eventArr.shift();
                await temp();
                timerArr.shift(); // 执行完再去掉
                if (eventArr.length) {
                    runner();
                } else {
                    isRunning = false;
                    return;
                }
            } else {
                isRunning = false;
                return;
            }
        }
    </script>
</html>

标签:eventArr,顺序,isRunning,动画,timerArr,添加,let,Promise,document
From: https://www.cnblogs.com/yalong/p/17935043.html

相关文章

  • 百度地图添加坐标点
    html<!DOCTYPEhtml><htmlxmlns="http://www.w3.org/1999/xhtml"><headrunat="server"><metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/><title>查看签到信息-地图&l......
  • KubeKey添加新节点
    KubeSphere使用一段时间之后,由于工作负载不断增加,可能需要水平扩展集群。自KubeSpherev3.0.0起,可以使用全新的安装程序 KubeKey 将新节点添加到集群。从根本上说,该操作是基于Kubelet的注册机制。换言之,新节点将自动加入现有的Kubernetes集群。1、工作准备需要一个单......
  • 快乐学Python,Python基础之如何控制代码执行顺序?【分支结构和循环结构】
    在上一篇文章中,我们所操作的所有代码都是顺序执行的。什么意思呢?就是我们在所有例子中的代码,计算机都是从第一句开始执行,执行完毕后执行第二句,以此类推,最终执行完整个代码块。以下面代码为例:print("FirstLine!")print("SecondLine!")print("ThirdLine!")输出结果:First......
  • 添加一个SQL Server身份验证方式
    关键几步如下,特别是最后一步,记得勾选SQLServer和Windows.    参考网址:如何在SQLSERVER的windows身份验证添加一个SQLServer身份验证方式_sqlserverwindows身份验证添加-CSDN博客 ......
  • 给数组循环遍历添加属性,数组数据打印出来实际已经添加了,但是页面数据并没有展示出来,该
    问题复述,即:在vue项目中中,会遇到修改完数据,但是视图却没有更新的情况问题原因:因为用某些方法修改完数据,vue框架是没办法监听到,无法做到数据响应式,导致数据实际修改了,但页面没展示出来     参考:https://blog.csdn.net/weixin_48998573/article/details/130620390......
  • Linux 添加静态路由
    Linux添加静态路由在日常使用中,服务器有两个IP地址,两块网卡的配置,访问不同网段,这种情况很常见。但我们需要创建额外的路由条目,以确定通过正确的网关转发数据包,使interface能够正常通信。以下在CentOS7测试通过一、使用route命令加入临时路由,重启后将失效route命令参数:add......
  • flutter 添加原生IOS 播放器
    定义播放器FlutterAVPlayer.swiftimportFoundationimportAVKitimportMediaPlayerimportFlutterclassFlutterAVPlayer:NSObject,FlutterPlatformView{privatevar_flutterAVPlayerViewController:AVPlayerViewController;init(frame:CGRect,......
  • spring MVC 后端 接收 前端 批量添加的数据(简单示例)
    <%@pagecontentType="text/html;charset=UTF-8"language="java"%><html><head>  <title>Title</title></head><body><scriptsrc="${pageScope.request.ContextPath}/js/jquery-3.3.1.min.js&qu......
  • C# 9.0 添加和增强的功能【基础篇】
    C#9.0添加和增强的功能【基础篇】 阅读目录一、记录(record)with表达式二、仅限Init的资源库三、顶级语句四、模式匹配增强功能五、模块初始值设定(ModuleInitializer)六、可以为null的引用类型规范七、目标类型的new表达式八、扩展分部方法九、静态匿名......
  • Windows平台如何实现RTSP拉流添加动态水印|视频处理后转推RTMP或轻量级RTSP服务
     技术背景我们在做Windows平台流数据转发的时候,除了常规的RTSP转RTMP推送外,还有个场景就是,好多开发者希望拉取的RTSP流,做二次视频分析,或者加动态水印等,处理后的数据,再二次编码推送到RTMP服务或轻量级RTSP服务。技术实现本文就以Windows平台拉取RTSP流,回调yuv数据到上层,处理后的数......