• 使用延时替代定时器


    这里分享的内容使用的是 js 语言,在其它语言也具有一样的原理。

    在实现定时执行某个任务时,有两种实现思路。

    1. 

    hInterval = setInterval(function(){
        task()
    }, 1000)

    // 如欲停止执行:
    clearInterval(hInterval)

    2.

    hTimeout = setTimeout(function f(){
       task()
       hTimeout = setTimeout(f, 1000)  // 通过延时递归实现反复执行
    }, 100)

    这两种做法严格的说是不相等的,后者由于 task() 执行需要耗费不等的时间,所以不存在稳定的间隔,前者可以保障稳定的间隔。

    尽管如此,这两种做法都适用于实际需求场景。

    但在实际编程时,由于切入点更多,后面的做法明显优于前者。

    setTimeout(function f(){
       task()
       if(xxx) setTimeout(f, 1000)  
       // else 则不再执行,通过前置条件可以在内部控制是否执行
       setTimeout(f, another delay /*可以灵活换间隔*/) 
       setTimeout(f2 /* 可以更换为执行另一个任务 */, 1000) 
    }, 100)

    我们看到,

    1. 添加一个前置的 if(cond) 就可以控制在满足特定条件时才反复执行。如使用定时器,则变为 if(){task()} else { 空转 },难以让定时器真正停下来。

    2. (根据 task 的结果,)可以在下一轮换成其它的延迟间隔。当然,对于定时器来说,也可以在代码内部设置间隔。

    3. 可以更换下一轮的任务。

    对于使用定时器遇到的常见的场景,开关定时器,使用 setTimeout 也更容易。

    function f(){
       task()
       setTimeout(f, 1000)
    }
    
    // 启动反复执行
    f()
    
    // 停止反复执行
    clearTimeout(h)
    // 但一般都会在 f 内部停止,很少由外部停止

    可以看到,启动定时任务和执行一个普通函数没有差别。

    另外,在网络编程中,网络任务耗时很难确定,定时器容易造成上一个任务未完成就启动下一个任务,引起并发问题,使用延迟方案则始终在一根线跑,也化解了潜在的并发陷阱。

    在其它语言里也有类似的设计,如 java 里有 Executor.schedule(runnable) 和 Executor.scheduleWithInterval() 两个函数,其语义和 setTimeout setInterval 对等。

  • 相关阅读:
    【ArchSummit干货分享】个推大数据金融风控算法实践
    Markdown 使用锚点
    部署ghost博客
    部署git server
    ubuntu 修改ssh远程主机名称,mac开机运行命令,静默方式启动virtual box虚拟机,静默执行run脚本
    meteor 实现 微信分享
    Android or iOS 运行 meteor App 屏幕一片空白 White screen的解决方法
    Ubuntu 修改用户密码与启动root账号
    meteor icons & splash配置
    meteor 安装 android sdk慢的改进方法
  • 原文地址:https://www.cnblogs.com/inshua/p/7808040.html
Copyright © 2020-2023  润新知