所以现在我在我的React应用程序中发生了一个非常奇怪的现象,我不完全确定如何描述它,但是这里有:
我正在构建一个带有Web Audio API和React的合成器,它响应keyDown
事件以触发音符和keyUp
事件的开始以触发音符的结束。大部分时间这都完美无瑕。但是,在每10-15人中,一次关键的压力导致在keyDown
事件之后发生了额外的keyUp
事件。我有一个React组件处理所有事件处理并根据正在处理的事件(keyUp
或keyDown
)触发Redux操作。另外,当用户持有密钥时,我正在使用lodash/debounce
方法来抑制其他keyDown
事件。
我不是坚持lodash/debounce
功能,我只需要一些东西来抑制额外的keyDown
事件。完全有可能我没有正确使用它或者有一个更简单的解决方案。我只需要答案。
我的组件如下:
import React, { Component } from 'react'
import debounce from 'lodash/debounce'
import { REGISTERED_KEYS } from '../constants/keyboard-constants'
export default class ComputerKeyboard extends Component {
constructor (props) {
super(props)
this.handleKeyDown = this.handleKeyDown.bind(this)
this.handleKeyUp = this.handleKeyUp.bind(this)
}
handleKeyDown (e) {
return debounce((event = e) => {
if (this.props.currentKeys.indexOf(event.keyCode) < 0 && REGISTERED_KEYS.includes(event.keyCode)) {
this.props.keyDown(event.keyCode)
this.props.updateGateStartTime({ value: this.props.audioContext.currentTime })
}
}, 2)()
}
handleKeyUp (e) {
const isLastKey = this.props.currentKeys.includes(e.keyCode) && this.props.currentKeys.length === 1
if (isLastKey && this.props.gateStartTime) {
this.props.updateGateStartTime({ value: null })
}
if (this.props.currentKeys.includes(e.keyCode) && REGISTERED_KEYS.includes(e.keyCode)) {
this.props.keyUp(e.keyCode)
}
}
componentDidMount () {
document.addEventListener('keydown', this.handleKeyDown)
document.addEventListener('keyup', this.handleKeyUp)
}
componentWillUnmount () {
document.removeEventListener('keydown', this.handleKeyDown)
document.removeEventListener('keyup', this.handleKeyUp)
}
render () {
return null
}
}
这是debounce
。一旦我删除了它,我再也没有看到错误。我试图获得幻想,但不理解节流和去抖动之间的区别。根据这个article:
限制强制执行可以随时间调用函数的最大次数。如“每100毫秒最多执行一次此功能”。
和
Debouncing强制执行一个函数不会被调用,直到一定时间过去而没有被调用。如“只有在没有被调用的情况下经过100毫秒才执行此函数”。
我的想法是,我可能想要节流,并且通过去抖,我允许函数的最后一次调用被允许通过,因为调用之间的时间足够短,偶尔在释放时,debounce让事件通过它应该没有。此外,由于密钥不再被按下并注册,因此handleKeyDown
中内置的故障安全逻辑不再适用,因为它预先假定实际存在密钥。