Skip to content
cpp
#pragma once
#include <boost/asio.hpp>
#include <functional>
#include <iostream>
#include <mutex>

class Throttler
{
public:
    typedef std::chrono::steady_clock Clock;
    typedef std::chrono::milliseconds Duration;
    typedef Clock::time_point TimePoint;

    Throttler(boost::asio::io_context& io, int intervalMs)
        : _timer(io), _interval(std::chrono::milliseconds(intervalMs)), _ready(true)
    {
    }

    ~Throttler() { _timer.cancel(); }

    template <typename F, typename... Args>
    void exectue(F&& f, Args&&... args)
    {
        // 获取当前时间
        auto now = Clock::now();
        // 计算剩余等待时间
        auto remaining = _interval - (now - _previous);

        // 取消之前的定时器(如果有)
        boost::system::error_code ec;
        _timer.cancel(ec);

        std::function<decltype(f(args...))()> func =
            std::bind(std::forward<F>(f), std::forward<Args>(args)...);

        // 如果不需要等待,立即执行函数
        if (remaining <= Duration::zero())
        {
            func();
            // 更新最后执行时间
            _previous = now;
        } else
        {
            // 需要等待,设置定时器延迟执行
            _timer.expires_after(remaining);
            // 异步等待定时器触发
            _timer.async_wait([this, func](const boost::system::error_code& ec) {
                // 定时器回调函数(在IO线程执行)
                if (!ec)
                {  // 只有定时器正常触发才执行 callback
                    func();
                    // 更新最后执行时间
                    _previous = Clock::now();
                }
            });
        }
    }

private:
    boost::asio::steady_timer _timer;
    Duration _interval;   // 节流时间间隔
    TimePoint _previous;  // 上次执行的时间点
    bool _ready;
};

基于 VitePress 构建