You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用RxJS操作符实现自定义定时器暂停并从上次记录值继续计时

解决方案

你可以结合RxJS的scan、takeUntil和switchMap操作符实现暂停继续的需求,核心思路是单独维护累计计时值,暂停时终止当前interval流,下次启动时基于上次保存的累计值继续累加计数,修改后的完整代码如下:

import { useState, useEffect } from 'react';
import { interval, Subject } from 'rxjs';
import { startWith, switchMap, takeUntil, map } from 'rxjs/operators';

const actionReset$ = new Subject();
const actionWait$ = new Subject();

function CustomTimer() {
  const [time, setTime] = useState(0);
  const [timerOn, setTimerOn] = useState(false);
  // 存储暂停时的计时值
  const [pausedTime, setPausedTime] = useState(0);

  useEffect(() => {
    let subscription;
    if (timerOn) {
      subscription = actionReset$.pipe(
        startWith(null),
        switchMap(() => {
          // 重置时清空暂停保存的数值
          setPausedTime(0);
          // 新的interval从0开始计数,加上之前暂停的数值得到当前总时间
          return interval(1000).pipe(
            map(sec => sec + 1 + pausedTime),
            // 点击wait时终止当前interval流
            takeUntil(actionWait$)
          );
        })
      ).subscribe(currentTime => {
        setTime(currentTime);
      });
    }

    return () => subscription?.unsubscribe();
  }, [timerOn, pausedTime]);

  // wait按钮点击回调
  const handleWait = () => {
    setTimerOn(false);
    // 保存当前的计时值,下次启动接着累加
    setPausedTime(time);
    actionWait$.next();
  };

  // reset回调
  const handleReset = () => {
    setTime(0);
    setPausedTime(0);
    actionReset$.next();
  };

  // 补全原代码缺失的stop点击回调
  const onStopClick = () => {
    setTimerOn(false);
    setTime(0);
    setPausedTime(0);
  }

  return (
    <div className="mainBlock">
      <h2>{time}秒</h2>
      {!timerOn && (
        <button onClick={() => setTimerOn(true)}>Start</button>
      )}
      {timerOn && (
        <button onClick={onStopClick}>Stop</button>
      )}
      {timerOn && (
        <button onClick={handleWait}>Wait</button>
      )}   
      {time > 0 && (
        <button onClick={handleReset}>Reset</button>
      )}   
    </div>  
  );
}

export default CustomTimer;

核心修改点说明

  • 新增pausedTime状态存储暂停时的计时值,下次启动interval时直接在新的计数基础上叠加该值,实现从暂停位置继续计时
  • 用takeUntil(actionWait$)操作符,点击wait按钮时自动终止当前运行的interval流,停止计数
  • 调整interval的映射逻辑,每次输出的计数值自动叠加之前暂停保存的数值,不需要额外修改计数逻辑
  • 补全了原代码中缺失的onStopClick回调逻辑,保证停止按钮功能正常

内容的提问来源于stack exchange,提问作者Александр Соколов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 19:36:05