Skip to content

Commit

Permalink
feat: add setIntervalByTimeout function
Browse files Browse the repository at this point in the history
  • Loading branch information
cc-hearts committed Oct 7, 2024
1 parent 3afaacd commit 78692c9
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 2 deletions.
33 changes: 32 additions & 1 deletion __test__/lib/validate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
isEffectiveNumber,
isPromise,
isValidArray,
isValidDate
isValidDate,
isPropertyKey
} from '../../lib'

describe('isArrayEquals', () => {
Expand Down Expand Up @@ -275,3 +276,33 @@ describe('isValidDate function', () => {
expect(isValidDate(invalidDate)).toBe(false)
})
})

describe('isPropertyKey function', () => {
test('should return true for a number', () => {
expect(isPropertyKey(123)).toBe(true)
})

test('should return true for a symbol', () => {
expect(isPropertyKey(Symbol('test'))).toBe(true)
})

test('should return false for an object', () => {
expect(isPropertyKey({})).toBe(false)
})

test('should return false for a function', () => {
expect(
isPropertyKey(() => {
/** */
})
).toBe(false)
})

test('should return false for null', () => {
expect(isPropertyKey(null)).toBe(false)
})

test('should return false for undefined', () => {
expect(isPropertyKey(undefined)).toBe(false)
})
})
51 changes: 50 additions & 1 deletion __test__/lib/workers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import {
executeConcurrency,
executeQueue,
pipe,
compose
compose,
setintervalByTimeout
} from '../../lib/workers'

const warningFn = (console.warn = jest.fn())
Expand Down Expand Up @@ -202,3 +203,51 @@ describe('compose', () => {
expect(composedFunction(5)).toEqual(5)
})
})

describe('setintervalByTimeout', () => {
test('setintervalByTimeout should call function at regular intervals', () => {
const fn = jest.fn()

jest.useFakeTimers()

// 设置间隔 1000ms 调用 fn
const clearMyInterval = setintervalByTimeout(fn, 1000)

jest.advanceTimersByTime(1000)
expect(fn).toHaveBeenCalledTimes(1)

jest.advanceTimersByTime(2000)
expect(fn).toHaveBeenCalledTimes(3)

// 清除定时器
clearMyInterval()

// 推进更多时间,fn 不应该再被调用
jest.advanceTimersByTime(3000)
expect(fn).toHaveBeenCalledTimes(3)

jest.useRealTimers()
})

test('setintervalByTimeout should handle async functions correctly', async () => {
const fn = jest.fn().mockResolvedValueOnce(null) // 模拟异步函数

jest.useFakeTimers()

const clearMyInterval = setintervalByTimeout(fn, 1000)

// 推进 1000ms,fn 应该被调用一次
jest.advanceTimersByTime(1000)
await Promise.resolve() // 等待异步执行完成
expect(fn).toHaveBeenCalledTimes(1)

// 推进 2000ms,fn 应该被调用两次
jest.advanceTimersByTime(2000)
await Promise.resolve() // 等待异步执行完成
expect(fn).toHaveBeenCalledTimes(3)

clearMyInterval()

jest.useRealTimers()
})
})
15 changes: 15 additions & 0 deletions lib/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,25 @@ export function isValidArray(arr: unknown[]): boolean {
return Array.isArray(arr) && arr.length > 0
}

/**
* Checks if a given value is a valid PropertyKey.
* A PropertyKey is a string, number, or symbol that can be used as a property name.
*
* @param val - The value to check.
* @return True if the value is a PropertyKey, false otherwise.
*/

export function isPropertyKey(val: unknown): val is PropertyKey {
return isStr(val) || isNumber(val) || isSymbol(val)
}

/**
* Checks if a given date is valid.
*
* @param date - The date to check.
* @return True if the date is valid, false otherwise.
*/

export function isValidDate(date: Date) {
return date.toString() !== 'Invalid Date'
}
30 changes: 30 additions & 0 deletions lib/workers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,33 @@ export function pipe(...fns: Array<Fn>) {
export function compose(...fns: Array<Fn>) {
return pipe(...fns.reverse())
}

/**
* Executes a given function repeatedly at a specified interval using setTimeout and clearTimeout.
*
* @param func - The function to be executed.
* @param delay - The interval (in milliseconds) at which the function should be executed.
* @return A function that, when called, clears the interval and stops the execution of the given function.
*/
export function setintervalByTimeout(func: Function, delay: number) {
let timer: number | NodeJS.Timeout | null = null

const fn = function () {
timer = setTimeout(async () => {
const res = func()
if (isPromise(res)) {
await res
}
fn()
}, delay)
}

const clearInterval = () => {
if (timer) {
clearTimeout(timer)
timer = null
}
}
fn()
return clearInterval
}

0 comments on commit 78692c9

Please sign in to comment.