异步计时器和 Enzyme

异步计时器和 Enzyme

在前端开发中,异步操作经常出现。异步计时器是常用的一种解决方案。而 Enzyme 是 React 生态系统中的一个工具库,用于编写测试代码。本文将介绍异步计时器和 Enzyme 的使用,以及还原一个实际的案例,帮助读者更好地掌握这两个技术。

异步计时器

在前端开发中,异步计时器十分常用,它可以延迟执行某些操作、轮询某些数据等。下面是几种常见的异步计时器。

setTimeout

setTimeout 可以在一定时间后执行一段代码,具体用法如下:

setTimeout(() => {
  console.log('Hello, World!')
}, 1000)

上述代码表示在 1 秒后输出 Hello, World!。

setInterval

setInterval 可以在一定时间间隔后重复执行某段代码,具体用法如下:

setInterval(() => {
  console.log('Hello, World!')
}, 1000)

上述代码表示每隔 1 秒输出一次 Hello, World!。

requestAnimationFrame

requestAnimationFrame 是一个浏览器提供的 API,用于在下一帧绘制前执行某段代码,具体用法如下:

function loop() {
  console.log('Hello, World!')
  requestAnimationFrame(loop)
}

loop()

上述代码表示每一帧绘制前输出一次 Hello, World!。

Enzyme

Enzyme 是 React 生态系统中的一个工具库,可以方便地编写测试代码。Enzyme 可以仿真一个组件渲染后的 HTML 结构,以及测试组件和 DOM 元素之间的交互。下面是一个简单的例子。

import Enzyme, { mount } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import MyComponent from './MyComponent'

Enzyme.configure({ adapter: new Adapter() })

it('should display correct message', () => {
  const wrapper = mount(<MyComponent name="World" />)
  expect(wrapper.find('p').text()).toBe('Hello, World!')
})

上述代码表示,先创建一个 MyComponent 组件,并传递一个属性 name,随后通过 mount 函数渲染这个组件。最后判断渲染出来的 HTML 结构中,是否存在一个文本为 Hello, World! 的 p 标签。

实例还原

接下来,我们将结合异步计时器和 Enzyme,还原一个实际的案例,帮助读者更好地掌握这两个技术。案例是一个带有倒计时和按钮的组件,在倒计时结束后触发一个回调函数。

CountdownTimer.js

首先,我们来看 CountdownTimer 组件的代码。这个组件接收一个时间戳和回调函数,通过 setInterval 每秒更新倒计时时间,最后在倒计时结束后触发回调函数。

import React, { useState, useEffect } from 'react'

function CountdownTimer({ timestamp, onEnd }) {
  const [timeLeft, setTimeLeft] = useState(Math.max(timestamp - Date.now(), 0))

  useEffect(() => {
    const intervalId = setInterval(() => {
      setTimeLeft(Math.max(timestamp - Date.now(), 0))
    }, 1000)

    return () => clearInterval(intervalId)
  }, [timestamp])

  useEffect(() => {
    if (timeLeft === 0) {
      onEnd()
    }
  }, [timeLeft, onEnd])

  const minutes = Math.floor(timeLeft / 1000 / 60)
  const seconds = Math.floor(timeLeft / 1000) % 60

  return (
    <>
      <p>{`${minutes}:${seconds.toString().padStart(2, '0')}`}</p>
    </>
  )
}

export default CountdownTimer
App.js

接下来,我们来看 App 组件的代码。这个组件通过一个按钮来启动 CountdownTimer 组件,当倒计时结束后,弹出一个提示框。

import React, { useState } from 'react'
import CountdownTimer from './CountdownTimer'

function App() {
  const [finish, setFinish] = useState(false)

  function handleEnd() {
    alert('Time is over!')
    setFinish(true)
  }

  function handleStart() {
    setFinish(false)
  }

  return (
    <>
      <button onClick={handleStart}>
        Start
      </button>
      {
        !finish ? (
          <CountdownTimer
            timestamp={Date.now() + 5000}
            onEnd={handleEnd}
          />
        ) : null
      }
    </>
  )
}

export default App
App.test.js

最后,我们来看 App 组件的测试代码。这个测试代码使用了 Enzyme 的 simulate 函数,模拟用户单击按钮的行为,随后判断是否触发了 alert。

import React from 'react'
import Enzyme, { mount } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import App from './App'

Enzyme.configure({ adapter: new Adapter() })

it('should display alert when time is over', () => {
  const wrapper = mount(<App />)
  wrapper.find('button').simulate('click')
  setTimeout(() => {
    expect(window.alert).toHaveBeenCalledWith('Time is over!')
  }, 5500)
})

上述代码表示,先创建一个 App 组件,并渲染这个组件。然后使用 simulate 函数,模拟用户单击 Start 按钮的行为。接着,等待 5.5 秒钟,判断是否触发了 alert。

总结

本文介绍了异步计时器和 Enzyme 的使用,以及还原了一个实际的案例。异步计时器是一个非常有用的工具,可以方便地进行延迟、轮询等操作。而 Enzyme 则可以方便地编写测试代码,测试组件和 DOM 元素之间的交互。相信读者通过本文的介绍和案例的还原,能够更好地掌握这两个技术。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a37f09add4f0e0ffba62a6


纠错反馈