【问题标题】:How do I use Promises with ´click´ events without adding event handler in the executor function?如何在不在 executor 函数中添加事件处理程序的情况下将 Promises 与“click”事件一起使用?
【发布时间】:2018-12-02 17:14:55
【问题描述】:

编辑:试图澄清问题并缩短它——我输入了一些代码来表明我试图解决这个问题,但我认为它只会混淆一些事情。

我是 Promise 新手,我正在尝试将一些现有代码(这很简单)转换为使用 Promise。

我想使用 Promise 将按钮单击链接到程序的其他部分,也就是说,我想将单击视为异步事件(例如,类似于 ajax 调用)。如何做到这一点?

从 MDN 文档中,promise 基本上是这样工作的

function myAsyncFunction(url) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open("GET", url);
    xhr.onload = () => resolve(xhr.responseText);
    xhr.onerror = () => reject(xhr.statusText);
    xhr.send();
  });
}

我完全理解这一点。据我了解,以下是可行的

function myPromiseGenerator() {
  return new Promise((resolve, reject) => {
   this.myButton.addEventListener('click',function(e) {
    /// do something to process the answer
    resolve(something);
    }
  });
}

但是我该如何移除事件监听器呢?我只想添加一次事件侦听器,而不是在每次调用 myPromiseGenerator 时添加,但我不知道如何使它工作。

一般来说,做我想做的事情的最佳方法是什么?感谢您的帮助。

【问题讨论】:

  • 不是很清楚你想要完成什么或者你想要解决的更高层次的问题是什么
  • 如果我有一个按钮,在 click 上应该根据当前程序状态指向任意数量的不同功能,有没有办法使用承诺来促进这一点?我的想法是创建一个返回承诺的函数,其中导致调用解析的异步事件是按钮单击。 Promise 的接收者根据程序状态确定接下来要调用什么,方法是将其传递给 Promise 的 then。我的问题是我必须在承诺生成器函数中添加“addEventListener”吗?我宁愿添加一次,而不是每次调用该函数。
  • 思维似乎倒退了。您不能只检查一个侦听器中的状态并做出相应的响应吗?
  • 我最初的做法是存储下一个要调用的函数,事件调度程序(链接到按钮)可以访问该函数。单击按钮 --> 调用事件调度程序 --> 调用存储函数。工作得很好,但我想看看它是否可以使用 Promise 来完成——对我来说,鼠标点击是一个异步事件,就像等待网络响应一样,所以它似乎适合......
  • 请注意,Promise 对于每个 Promise 发生一次的异步事件很有用。 waitForNextClick 作为 Promise 名称是有意义的,因为 nextClick 是单个事件,但 everyClick 作为 Promise 没有多大意义,因为 Promise 只能解决一次。如果您想在每次发生异步事件时都做某事,通常最好只使用回调。尽管我们也有 Promise,但在很多地方回调仍然有用。任何使用订阅模式(如 EventEmitters 或 pub/sub)的东西都必然使用回调。

标签: javascript ecmascript-6 promise


【解决方案1】:

只需使用事件监听器的once 选项:

function myPromiseGenerator() {
  return new Promise((resolve, reject) => {
    this.myButton.addEventListener('click',function(e) {
        /// do something to process the answer
        resolve(something);
    }, {once: true});
  });
}

【讨论】:

    【解决方案2】:

    你可以做你最初打算做的事情——移除事件监听器——如果你给匿名处理函数一个名字:

    async function myPromiseGenerator() {
        return new Promise(resolve => {
            this.myButton.addEventListener('click',
                async function handler(event) {
                    this.myButton.removeEventListener('click', handler);
                    // Assume a login code has been entered - validate it
                    if (await validateAccessCode())
                        resolve(true)
                    else
                        resolve(false);
                });
        });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-08
      • 2019-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多