更好地处理Promise.race

问题描述 投票:0回答:1

尝试为绘图工具编写流程逻辑,用户可以在其中输入键盘输入以在卡瓦斯上绘图,比方说,为了实现这一目标,我尝试以一种一旦完成就将其自身删除的方式链接事件侦听器。我宁愿这样做,也不愿跟踪管理哪些侦听器处于活动状态的全局状态等。我正在取得进展,但我陷入了对

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();

javascript event-handling
1个回答
0
投票

我认为递归方法根本没有必要,但这很难确定,因为不清楚你想用它实现什么。既然您谈到绘图工具,我假设您希望根据之前发生的事件来阻止某些事件的处理。

例如,开始绘图的事件后面必须跟着另一个完成绘图的事件(或“退出”按钮),但不能再跟另一个“开始绘图”事件。这可以通过仅添加一次的事件处理程序来实现,但其行为取决于

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>

© www.soinside.com 2019 - 2024. All rights reserved.