Skip to content

React实现debounce过程与总结 #17

@oufeng

Description

@oufeng

关注点

  • SyntheticEvent和event pooling(React 17 on the web does not use event pooling)
    • SyntheticEvent基于本机浏览器事件的包装。因此在不同浏览器中具有相同的属性,也可以通过nativeEvent属性本机浏览器事件。
    • 对本机浏览器事件进行包装可能会导致性能问题。因为创建包装器时需要考虑垃圾回收,是比较消耗CPU的。
    • React通过event pooling来解决上述问题。当触发事件时都会从event pooling获取一个实例,并填充相关属性。当事件处理完成运行后所有属性都将无效,实例也将释放。
    • 所以回调函数的处理逻辑触及到异步的话,可能会取不到真实的event。可通过e.persist()来避免。
  • 一个组件实例只创建一个debounce(throttled) function。不要在事件触发时重新创建debounce(throttled) function
  • react hook可以考虑用useConstant避免重新创建debounce(throttled) function
  • debounce函数要将promise也考虑上

code

debounce

const debounce = (func, wait) => {
    let timeout

    // This is the function that is returned and will be executed many times
    // We spread (...args) to capture any number of parameters we want to pass
    return function executedFunction(...args) {
        // The callback function to be executed after
        // the debounce time has elapsed
        const later = () => {
            // null timeout to indicate the debounce ended
            timeout = null

            // Execute the callback
            func(...args)
        }
        // This will reset the waiting every function execution.
        // This is the step that prevents the function from
        // being executed because it will never reach the
        // inside of the previous setTimeout
        clearTimeout(timeout)

        // Restart the debounce waiting period.
        // setTimeout returns a truthy value (it differs in web vs Node)
        timeout = setTimeout(later, wait)
    }
}

debouncePromise

export const debouncePromise = (func, wait) => {
    let timeout
    let resolve = null

    return function executedFunction(...args) {
        const later = () => {
            timeout = null

            // Execute the callback
            resolve(func(...args))
            resolve = null
        }
        clearTimeout(timeout)
        timeout = setTimeout(later, wait)
        return new Promise((r) => (resolve = r))
    }
}

参考

Perform debounce in React.js
Event Pooling

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions