web worker实现倒计时

Others 2023-01-29 10:54:21 2023-01-29 10:54:21 845 次浏览

<CountDownTimer endTime={1569834068266} onEnd={this.onEndHandler.bind(this)} />


CountDownTimer.jsx

import React from "react";
import styled from "styled-components";
import WebWorker from "../../utils/worker";

let work = function() { let timer = null; this.onmessage = e => { const { endTime, state } = e.data; if (state === "stop") { if (timer) { clearInterval(timer); timer = null; } return; } else if (state === "start") { let interval = 1000; if (!timer) { timer = setInterval(() => { this.postMessage(endTime - new Date().getTime()); }, interval); } } }; };

let worker = new WebWorker(work);

/**

  • 计算相对时间字符串
  • @param {number} time 13位时间戳 */ function relativeTime(time) { if (time <= 0) { return "00:00"; } const minute = Number.parseInt(time / 1000 / 60, 10); const second = Number.parseInt((time / 1000) % 60, 10); return ${minute &gt; 9 ? minute : "0" + minute}:${ second &gt; 9 ? second : "0" + second }; }

export default function CountDownTimer({ endTime, onEnd = Function.prototype }) { const initTime = relativeTime(endTime - new Date().getTime()); let [time, setTime] = React.useState(initTime);

worker.onmessage = e => { if (e.data <= 0) { worker.postMessage({ state: "stop" }); return; } setTime(relativeTime(e.data)); };

React.useEffect(() => { worker.postMessage({ state: "start", endTime: Number.parseInt(endTime, 10) }); return function() { worker.postMessage({ state: "stop" }); }; }, [endTime]);

React.useEffect(() => { if (time === "00:00") { return function() { onEnd(); worker.postMessage({ state: "stop" }); }; } }, [time, endTime, onEnd]);

const Time = styled.span font-size: 1.6rem; font-weight: 700; vertical-align: middle; ; return ( <div> 倒计时:<Time>{time}</Time> </div> ); }

worker.js

export default class WebWorker {
  constructor(worker) {
    const code = worker.toString();
    const blob = new Blob([`(${code})()`]);
    return new Worker(URL.createObjectURL(blob));
  }
}