【问题标题】:Resolve promise on external event解决外部事件的承诺
【发布时间】:2020-12-18 03:30:02
【问题描述】:

我想在不同函数中发生事件时解决一个承诺

const trigger = function() {}

const eventHandler = async function() {
  while(true) {
    await new Promise (resolve => {
      
    }
    // Code when the promise fulfills.
  }
}

const cleaner = function() {
  trigger()
}

cleaner()

【问题讨论】:

    标签: javascript promise callback


    【解决方案1】:

    您可以通过重新分配trigger 轻松做到这一点:

    let trigger = () => {}
    
    const eventHandler = async function() {
      while(true) {
        await new Promise (resolve => {
          trigger = resolve
    //    ^^^^^^^^^^^^^^^^^
        }
        // Code when the promise fulfills.
      }
    }
    
    const cleaner = function() {
      trigger() // calls resolve to fulfill the currently waited-for promise
    }
    
    eventHandler() // start waiting
    cleaner()
    

    但是,请注意,这通常被认为是一种不好的做法,您应该启动任何导致外部事件的方法,尤其是安装事件侦听器,new Promise 执行器回调中,您可以在其中可以轻松访问resolve 函数。

    【讨论】:

      【解决方案2】:

      下面是一个示例,说明如何使承诺可取消。我们使用了一个辅助函数 makeCancelable() ,它接受一个承诺,并返回一个不同的承诺和一个取消函数。没有办法只是“取消”现有的承诺,特别是当你无法控制承诺的做出方式时,但你可以做的是将现有的承诺包装在一个新的承诺中,它的行为就像原来的一样,但是也准备好根据命令解析。

      // Helper function that just waits for a timeout
      const wait = ms => new Promise(resolve => setTimeout(resolve, ms))
      
      function makeCancelable(promise) {
        let resolveWrappedPromise
        return {
          promise: new Promise((resolve, reject) => {
            resolveWrappedPromise = resolve
            promise.then(resolve, reject)
          }),
          cancel: value => resolveWrappedPromise(value),
        }
      }
      
      cancelPromise = () => {} // function used by onClick event
      async function eventHandler() {
        while (true) {
          const { promise, cancel } = makeCancelable(wait(1000).then(() => 'Success!'))
          cancelPromise = cancel
          console.log(await promise)
        }
      }
      
      eventHandler()
      <button onclick="cancelPromise('Canceled!')">Cancel!</button>

      在此代码示例中,“成功!”将每秒打印一次 - 除非您按下按钮取消当前的承诺。重复按下按钮将延迟“成功!”被打印的不确定,因为承诺被取消并提供了值“取消!”取消发生的时间。

      【讨论】:

        【解决方案3】:

        使用 EventEmitter2 包 (Live demo) 的 waitFor 方法。

        import EventEmitter2 from "eventemitter2";
        
        const emitter = new EventEmitter2();
        
        (async () => {
          const data = await emitter.waitFor("test");
          console.log("emitted", data);
        })();
        
        setTimeout(() => emitter.emit("test", 1, 2, 3), 1000); 
        

        【讨论】:

          猜你喜欢
          • 2015-06-24
          • 1970-01-01
          • 2018-04-02
          • 2014-08-10
          • 1970-01-01
          • 2021-08-11
          • 2019-09-29
          • 1970-01-01
          相关资源
          最近更新 更多