javascript - 有没有办法干净地创建一个在鼠标左键向上或向下后解决的承诺?
问题描述
在我的客户代码中,我有
const whatMouseDid = await mouseDoesSomething()
后一个函数看起来像:
async mouseDoesSomething() {
const mouseUp = (resolve) => {
const handler = (evt) => {
if (evt.button === 0)
resolve("up")
}
return handler
}
const mouseDown = (resolve) => {
const handler = (evt) => {
if (evt.button === 0)
resolve("down")
}
return handler
}
return new Promise((resolve, reject) => {
document.addEventListener('mouseup', mouseUp(resolve))
document.addEventListener('mousedown', mouseDown(resolve))
})
}
这已经比我希望的要复杂一些,但仍然可以管理。但是,有一个问题 - 侦听器永远不会被删除。而且因为我需要传递对 的引用Promise.resolve
,所以我不removeEventListener
容易。我能想到的唯一方法是保留一个可变的处理程序列表以及分配给它们的事件、目标等,并在处理程序函数中迭代该列表并删除附加的处理程序。可选参数{once: true}
也不起作用,因为如果单击的按钮不是我想要的,我无法解决。
这一切都让人感觉非常复杂,让我觉得我只是错过了明显的简单方法;我是吗?还是真的有这么多麻烦?
解决方案
而且因为我需要传入对 Promise.resolve 的引用,所以我不能轻易地删除EventListener。我能想到的唯一方法是保留一个可变列表
为什么这么复杂?您在 Promise 执行器中创建函数,只需引用它们。
mouseDoesSomething() {
return new Promise((resolve, reject) => {
const mouseUphandler = evt => {
if (evt.button === 0) {
resolve("up")
document.removeEventListener('mouseup', mouseUpHandler)
document.removeEventListener('mousedown', mouseDownHandler)
}
}
const mouseDownhandler = evt => {
if (evt.button === 0) {
resolve("down")
document.removeEventListener('mouseup', mouseUpHandler)
document.removeEventListener('mousedown', mouseDownHandler)
}
}
document.addEventListener('mouseup', mouseUpHandler)
document.addEventListener('mousedown', mouseDownHandler)
})
}
当然这是很多代码重复,但是您可以通过动态创建处理程序来再次抽象它 - 您只需要在声明两个处理程序的范围内执行它:
mouseDoesSomething() {
return new Promise((resolve, reject) => {
const makeHandler = dir => evt => {
if (evt.button === 0) {
resolve(dir)
document.removeEventListener('mouseup', mouseUpHandler)
document.removeEventListener('mousedown', mouseDownHandler)
}
}
const mouseUphandler = makeHandler("up")
const mouseDownhandler = makeHandler("down")
document.addEventListener('mouseup', mouseUpHandler)
document.addEventListener('mousedown', mouseDownHandler)
})
}
推荐阅读
- r - 如何使用逻辑索引和 grepl 来舍入数据框中的特定列
- python - 获取 Pygame 键盘输入并检查它是否是数字
- python - “ProgrammingError:没有结果。以前的 SQL 不是查询。” 在尝试截断表格时
- android - Delphi 无法启动Android 8 以上版本的Android Service
- routes - 我已经使用 docker 在我的机器上为印度设置了 osm !我如何编辑 pbf 文件中的印度 osm 地图
- javascript - 根据元素模式中的第一个短语对数组元素重新排序
- javascript - Reactjs - 抽认卡组件 - 自动检测容器宽度/高度以提供图像类
- amazon-web-services - 如何让 Terraform 读取 AWS 凭证文件?
- linux - 如何从字面上比较'*'作为linux中的字符串
- java - Netbeans 12.0 - 从 DB 生成实体类使用 Java Date 类而不是 LocalDate