【问题标题】:How to let JavaScript wait until certain event happens?如何让 JavaScript 等到某个事件发生?
【发布时间】:2011-08-01 17:51:15
【问题描述】:

我正在编写一个具有以下结构的网页:

  1. 一个部分(表 A)依赖于另一个部分(表 B);
  2. 另一个部分(表 B)包含需要在每次更新时重新计算的元素。计算由外部工具处理,完成后会引发事件。

为了保证正确性,只有在另一个表完全更新(即完成计算)之后才需要更新该表。但是,我不知道如何有效地实现这一点,并且我在 JavaScript 中找不到任何 wait 工具。

目前,我正在使用以下方法:

  1. 声明一个全局变量updated并使其成为false;
  2. 第一个表收到输入后,我创建一个空的while 循环,直到updated 为true;
  3. 添加监听器,一旦计算完成并接收到事件,将updated设置为true。

这对我来说似乎不直观,但我想不出任何其他方法。有什么好的方法吗?

感谢您的任何意见!

【问题讨论】:

    标签: javascript events web-applications wait


    【解决方案1】:

    在 2022 年,拥有一个触发 Promise(可用于 Promise 链或异步/等待代码)的事件侦听器非常有用。一种干净的制作方法:

    function getPromiseFromEvent(item, event) {
      return new Promise((resolve) => {
        const listener = () => {
          item.removeEventListener(event, listener);
          resolve();
        }
        item.addEventListener(event, listener);
      })
    }
    
    async function waitForButtonClick() {
      const div = document.querySelector("div")
      const button = document.querySelector("button")
      div.innerText = "Waiting for you to press the button"
      await getPromiseFromEvent(button, "click")
      div.innerText = "The button was pressed!"
    }
    waitForButtonClick()
    <button>ClickMe</button>
    <div></div>

    【讨论】:

    • 先生,您是救生员。谢谢一吨
    【解决方案2】:

    添加一个监听器,一旦计算完成并接收到事件,设置更新为true。

    不要将updated 设置为true,然后等待updated 为true - 只需在侦听器中执行您想做的任何事情。

    myEventBus.addListener(function () {
        // do whatever
        updateTable();
        alert('table updated!');
    });
    

    【讨论】:

      【解决方案3】:

      做空的while循环是个坏主意。您不仅会消耗 CPU 周期,而且 Javacript 是单线程的,因此您将永远循环,而不会给任何人更改变量的机会。

      您可以做的是重写有其他人依赖它的表以“触发事件本身”。有很多方法可以做到这一点,但基本上你只是希望它调用一个“继续”函数而不是盲目地返回。这个函数可以是预定义的,或者你可以将它作为参数传递给某个地方。

      //this is just illustrative
      //Your actual code will be probably very different from this.
      
      function update_part(){
          //do something
          signal_finished_part()
      }
      
      var parts_done = 0;
      function signal_finished_part(){
          parts_done ++;
          if(parts_done >= 5){
              signal_all_parts_done();
          }
      }
      
      function signal_all_parts_done()
      {
          //do something to table A
      }
      

      【讨论】:

        【解决方案4】:

        您可以为触发更新的任何内容编写回调函数。为避免混乱的回调,您也可以使用 Promise,并根据更新操作中检索到的数据更新表的部分内容。接受建议。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-06-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多