Skip to content
medium
链式调用任务队列异步

LazyMan 懒惰的人

LazyMan除了吃就是睡,很lazy。

LazyMan(name: string, logFn: (log: string) => void) 通过传入logFn打印信息。

基本使用:

js
LazyMan('Jack', console.log)
// Hi, I'm Jack.

可以eat(food: string):

js
LazyMan('Jack', console.log)
  .eat('banana')
  .eat('apple')
// Hi, I'm Jack.
// Eat banana.
// Eat apple.

可以sleep(time: number),单位是秒:

js
LazyMan('Jack', console.log)
  .eat('banana')
  .sleep(10)
  .eat('apple')
  .sleep(1)
// Hi, I'm Jack.
// Eat banana.
// Wake up after 10 seconds.
// Eat apple.
// Wake up after 1 second.

sleepFirst(time: number)的话,无论顺序如何,最优先sleep:

js
LazyMan('Jack', console.log)
  .eat('banana')
  .sleepFirst(10)
  .eat('apple')
  .sleep(1)
// Wake up after 10 seconds.
// Hi, I'm Jack.
// Eat banana.
// Eat apple.
// Wake up after 1 second.

请创建一个如此懒惰的LazyMan()。

题目模版

js
/**
 * @param {string} name
 * @param {(log: string) => void} logFn
 */
export default function LazyMan(name, logFn) {

}
ts
export default function LazyMan(name: string, logFn: (log: string) => void) {

}

测试代码

js
import { describe, expect, it, vi } from 'vitest'
import LazyMan from './LazyMan'

describe('day20-LazyMan', () => {
  it('应该支持基本的链式调用', async () => {
    const mockLog = vi.fn()

    LazyMan('Jack', mockLog)

    // 等待异步执行完成
    await new Promise(resolve => setTimeout(resolve, 0))

    expect(mockLog).toHaveBeenCalledTimes(1)
    expect(mockLog).toHaveBeenCalledWith('Hi, I\'m Jack.')
  })

  it('应该支持 eat 方法', async () => {
    const mockLog = vi.fn()

    LazyMan('Jack', mockLog)
      .eat('banana')
      .eat('apple')

    // 等待异步执行完成
    await new Promise(resolve => setTimeout(resolve, 0))

    expect(mockLog).toHaveBeenCalledTimes(3)
    expect(mockLog).toHaveBeenNthCalledWith(1, 'Hi, I\'m Jack.')
    expect(mockLog).toHaveBeenNthCalledWith(2, 'Eat banana.')
    expect(mockLog).toHaveBeenNthCalledWith(3, 'Eat apple.')
  })

  it('应该支持 sleep 方法', async () => {
    const mockLog = vi.fn()

    const startTime = Date.now()
    LazyMan('Jack', mockLog)
      .eat('banana')
      .sleep(1)
      .eat('apple')

    // 等待异步执行完成
    await new Promise(resolve => setTimeout(resolve, 1100))

    const endTime = Date.now()
    const duration = endTime - startTime

    expect(duration).toBeGreaterThanOrEqual(1000)
    expect(mockLog).toHaveBeenCalledTimes(4)
    expect(mockLog).toHaveBeenNthCalledWith(1, 'Hi, I\'m Jack.')
    expect(mockLog).toHaveBeenNthCalledWith(2, 'Eat banana.')
    expect(mockLog).toHaveBeenNthCalledWith(3, 'Wake up after 1 seconds.')
    expect(mockLog).toHaveBeenNthCalledWith(4, 'Eat apple.')
  })

  it('应该支持 sleepFirst 优先执行', async () => {
    const mockLog = vi.fn()

    LazyMan('Jack', mockLog)
      .eat('banana')
      .sleepFirst(1)
      .eat('apple')
      .sleep(1)

    // 等待异步执行完成
    await new Promise(resolve => setTimeout(resolve, 2100))

    expect(mockLog).toHaveBeenCalledTimes(5)
    expect(mockLog).toHaveBeenNthCalledWith(1, 'Wake up after 1 seconds.')
    expect(mockLog).toHaveBeenNthCalledWith(2, 'Hi, I\'m Jack.')
    expect(mockLog).toHaveBeenNthCalledWith(3, 'Eat banana.')
    expect(mockLog).toHaveBeenNthCalledWith(4, 'Eat apple.')
    expect(mockLog).toHaveBeenNthCalledWith(5, 'Wake up after 1 seconds.')
  })
})
ts
import { describe, expect, it, vi } from 'vitest'
import LazyMan from './LazyMan'

describe('day20-LazyMan', () => {
  it('应该支持基本的链式调用', async () => {
    const mockLog = vi.fn()

    LazyMan('Jack', mockLog)

    // 等待异步执行完成
    await new Promise(resolve => setTimeout(resolve, 0))

    expect(mockLog).toHaveBeenCalledTimes(1)
    expect(mockLog).toHaveBeenCalledWith('Hi, I\'m Jack.')
  })

  it('应该支持 eat 方法', async () => {
    const mockLog = vi.fn()

    LazyMan('Jack', mockLog)
      .eat('banana')
      .eat('apple')

    // 等待异步执行完成
    await new Promise(resolve => setTimeout(resolve, 0))

    expect(mockLog).toHaveBeenCalledTimes(3)
    expect(mockLog).toHaveBeenNthCalledWith(1, 'Hi, I\'m Jack.')
    expect(mockLog).toHaveBeenNthCalledWith(2, 'Eat banana.')
    expect(mockLog).toHaveBeenNthCalledWith(3, 'Eat apple.')
  })

  it('应该支持 sleep 方法', async () => {
    const mockLog = vi.fn()

    const startTime = Date.now()
    LazyMan('Jack', mockLog)
      .eat('banana')
      .sleep(1)
      .eat('apple')

    // 等待异步执行完成
    await new Promise(resolve => setTimeout(resolve, 1100))

    const endTime = Date.now()
    const duration = endTime - startTime

    expect(duration).toBeGreaterThanOrEqual(1000)
    expect(mockLog).toHaveBeenCalledTimes(4)
    expect(mockLog).toHaveBeenNthCalledWith(1, 'Hi, I\'m Jack.')
    expect(mockLog).toHaveBeenNthCalledWith(2, 'Eat banana.')
    expect(mockLog).toHaveBeenNthCalledWith(3, 'Wake up after 1 seconds.')
    expect(mockLog).toHaveBeenNthCalledWith(4, 'Eat apple.')
  })

  it('应该支持 sleepFirst 优先执行', async () => {
    const mockLog = vi.fn()

    LazyMan('Jack', mockLog)
      .eat('banana')
      .sleepFirst(1)
      .eat('apple')
      .sleep(1)

    // 等待异步执行完成
    await new Promise(resolve => setTimeout(resolve, 2100))

    expect(mockLog).toHaveBeenCalledTimes(5)
    expect(mockLog).toHaveBeenNthCalledWith(1, 'Wake up after 1 seconds.')
    expect(mockLog).toHaveBeenNthCalledWith(2, 'Hi, I\'m Jack.')
    expect(mockLog).toHaveBeenNthCalledWith(3, 'Eat banana.')
    expect(mockLog).toHaveBeenNthCalledWith(4, 'Eat apple.')
    expect(mockLog).toHaveBeenNthCalledWith(5, 'Wake up after 1 seconds.')
  })
})

答案

类型路径
JS 版本problems/Day 20/answer.js
TS 版本待补充
Review待补充

内容基于 MIT 许可 | 保持节奏 · 持续积累