• 实时更新进度条:JavaScript中的定时器和异步编程技巧


    前言

            在Web开发中,有许多场景需要实时地更新页面上的进度,例如上传文件、数据处理等。本文将介绍如何利用JavaScript中的定时器和异步编程技巧来实现实时更新进度,并探讨一些其他解决方案。

            处理进度实时更新:

    利用异步编程实现实时进度更新

            利用async/await结合Promise可以让代码看起来更加清晰,同时实现实时更新的效果。

    1. <el-table>
    2. <el-table-column label="进度" width="120" align="center">
    3. <template slot-scope="scope">
    4. <el-progress :percentage="Math.round(scope.row.progress * 100)" color="#00E2AE">el-progress>
    5. template>
    6. el-table-column>
    7. <el-table-column label="操作" align="center">
    8. <template slot-scope="scope">
    9. <img src="..." alt="" @click="reloadTask(scope.row)" />
    10. template>
    11. el-table-column>
    12. el-table>
    1. reloadTask(row) {
    2. row.progress = 0;
    3. this.$API.POST('/interface/', data)
    4. .then(async Response => {
    5. if (Response.code === 200) {
    6. while (row.progress < 1) {
    7. await this.$API.GET('/interface/', params)
    8. .then(response => {
    9. if (response.code === 200) {
    10. row.progress = response.data.progress;
    11. }
    12. })
    13. await new Promise(resolve => setTimeout(resolve, 500)); // 等待500毫秒
    14. }
    15. }
    16. else {
    17. this.$errorMsg(response["data"]["msg"]);
    18. row.progress = 1;
    19. }
    20. })
    21. .catch(error => {
    22. this.$errorMsg(error);
    23. row.progress = 1;
    24. })
    25. }

            在上述代码中,代码会首先将进度初始化为0。然后,通过发送POST请求来触发任务的开始。随后,在一个while循环中,代码会以一定的时间间隔(这里是500毫秒)发送GET请求来获取最新的进度。通过不断轮询的方式,直到进度达到100%时退出循环。在等待的过程中,使用了await关键字来等待Promise对象解析(即等待异步请求完成)和setTimeout函数延时。这样就实现了实时更新进度的效果。        

            如果直接使用setTimeout而没有使用await,那么setTimeout将不会造成循环的间隔。因为JavaScript中,setTimeout是非阻塞的,它会在指定的时间后将回调函数放入事件队列,然后继续执行后续的代码,而不会等待定时器的回调执行完成。

            轮询:

    其余方法

    Generators和yield

            使用Generators和yield可以编写出具有异步特性的代码,实现实时更新。

    1. function* updateProgress() {
    2. while (true) {
    3. // 更新逻辑
    4. const value = yield new Promise((resolve) => setTimeout(resolve, 1000)); // 每秒钟等待
    5. if (value === '终止条件') {
    6. break; // 退出循环
    7. }
    8. }
    9. }
    10. const updater = updateProgress();
    11. const updateLoop = () => {
    12. updater.next().value.then(updateLoop);
    13. };
    14. updateLoop();

            在上述代码中,定义了一个Generator函数updateProgress,它使用while (true)循环来更新进度条。在每次循环中,使用yield关键字返回一个Promise对象,并利用setTimeout函数来实现一定的时间间隔(这里是1秒)。然后,通过调用updater.next().value.then(updateLoop)来启动一个无限循环的更新过程。每次调用next()方法时,都会让Generator函数执行到下一个yield表达式,并返回相应的Promise对象。通过这种方式,可以实现间歇性地更新进度。

    其他解决方案

            虽然HTTP V1和V2是基于全双工的TCP协议;但是HTTP 1.0和1.1分别采用了单工和半双工的传输模式,HTTP 2.0引入了多路复用( Multiplexing )的特性,通过单一的TCP连接传输多个请求和响应,从而提高了性能和效率。然而,尽管HTTP 2.0在性能方面有所改进,它仍然是基于请求-响应模式的协议,并没有提供真正的全双工通信。

            对于需要实时性的应用程序,像WebSocket和Server-Sent Events( SSE )这样的专门为实时通信设计的协议可能更合适,因为它们提供了双向通信通道并具备更低的延迟。

    结语     

            本文介绍了如何利用JavaScript中的定时器和异步编程技巧实现实时更新进度的效果,同时也探讨了一些其他解决方案。根据具体场景的需求,选择合适的方法来实现实时更新将会极大地改善用户体验。

  • 相关阅读:
    HCIA网络课程第六周作业
    2023最新SSM计算机毕业设计选题大全(附源码+LW)之java教学信息管理辅助系统jszpb
    MySQL夺命10问,你能坚持到第几问?
    8月Node服务的3场事故
    绿色通道——单调队列加二分加dp——修建草坪——单调队列+dp——理想的正方西——二维单调队列
    uniapp小程序实现上下固定中间滑动布局(附源码和实现过程讲解)
    CAS:1260586-88-6_生物素-C5-叠氮_Biotin-C5-Azide
    谷粒商城学习笔记
    java.util.Arrays 快速使用介绍
    java switch case 多条件 正确案例&错误案例
  • 原文地址:https://blog.csdn.net/qq_51588894/article/details/133176364