尝试为绘图工具编写流程逻辑,用户可以在其中输入键盘输入以在卡瓦斯上绘图,比方说,为了实现这一目标,我尝试以一种一旦完成就将其自身删除的方式链接事件侦听器。我宁愿这样做,也不愿跟踪管理哪些侦听器处于活动状态的全局状态等。我正在取得进展,但我陷入了对
Promise.race
的反复调用,不确定是否有更好的方法来实现这一点。
在递归循环中使用 Promise.race 意味着很多 Promise 没有得到解决。 我有更好的方法吗?
function startCount(node) {
const counter = Object.create(counterMethods);
counter.node = node;
counter.number = 0;
counter.exitloopflag = false;
return counter;
}
const counterMethods = {
doCounter: function() {
return new Promise((resolve) => {
let handler = () => {
console.log("click");
this.node.removeEventListener("click", handler);
resolve();
};
this.node.addEventListener("click", handler);
});
},
quit: function() {
return new Promise((resolve) => {
let handler = (e) => {
if (e.key === "Escape") {
this.node.removeEventListener("keydown", handler);
resolve("exit");
}
};
this.node.addEventListener("keydown", handler);
});
},
counterFlow: function() {
if (this.exit) return;
Promise.race([this.doCounter(), this.quit()]).then((value) => {
//<-- not confident about this
console.log(`The value is !!!: ${value}`);
if (value === "exit") {
this.exit = true;
} else {
this.number += 1;
console.log(`you have clicked ${this.number} times`);
this.counterFlow(); //<-- recursive call, means I'm leaving a lot of unresolved promises.
}
});
},
};
let obj = new startCount(document);
obj.counterFlow();
我认为递归方法根本没有必要,但这很难确定,因为不清楚你想用它实现什么。既然您谈到绘图工具,我假设您希望根据之前发生的事件来阻止某些事件的处理。
例如,开始绘图的事件后面必须跟着另一个完成绘图的事件(或“退出”按钮),但不能再跟另一个“开始绘图”事件。这可以通过仅添加一次的事件处理程序来实现,但其行为取决于
state
变量。
以下代码片段说明了这一点:单击、拖动并释放鼠标会绘制一个矩形,其起点和终点为对角点。
var x, y;
var state = "idle";
document.addEventListener("keydown", function(event) {
if (event.key === "Escape") state = "inactive";
});
document.addEventListener("mousedown", function(event) {
if (state === "idle") {
x = event.x;
y = event.y;
state = "drawing";
}
});
document.addEventListener("mouseup", function(event) {
if (state === "drawing") {
box.style.top = y + "px";
box.style.height = (event.y - y) + "px";
box.style.left = x + "px";
box.style.width = (event.x - x) + "px";
state = "idle";
}
});
body {
position: relative;
}
#box {
border: solid 1px black;
position: absolute;
}
<div id="box"></div>