【问题标题】:How to convert trigger/event into Promise or async/await?如何将触发器/事件转换为 Promise 或 async/await?
【发布时间】:2020-12-28 16:16:40
【问题描述】:

我正在尝试将回调函数转换为异步/等待。该代码使用从主窗口框架到 iframe 的 postMessage。当 iframe 发回消息时,它会调用回调函数。有什么方法可以从$(window).on(...) 模式转换为 Promise?

工作代码的最小版本:

调用函数:

window.bridge.post(cb);

桥对象:

class Bridge {
  constructor(win, root) {
    this.win = win;
    this.root = root;
    this.bindEvents();

    this.post = this.factoryMethod('post', 'postResult');

  }

  post(eventName, paramObject) {
    this.win.postMessage([eventName, JSON.stringify(paramObject)], this.root);
  }

  bindEvents() {
    window.addEventListener('message', e => this.handleEvents(e));
  }

  handleEvents(e) {
    const eventName = e.data[0];
    const eventObj = e.data[1];
    if (typeof eventName !== 'undefined' && eventName != null) {
      $(window).trigger(eventName, eventObj);
    }
  }

  factoryMethod(msgIn, msgOut) {
    return (cb) => {
      this.post(msgIn, {});
      $(window).on(msgOut, (e, arg) => cb(arg));
    };
  }

}

export default Bridge;

提前致谢。

【问题讨论】:

  • new Promise(resolve => $(window).once(msgOut, resolve))?
  • once 还是on?这会允许window.bridge.post().then(fun) 吗?我认为 post 函数必须返回一个 Promise 对吗?
  • once - 承诺只能一次结算,对于多条消息,您需要单独的承诺。这就是为什么它们不太适合事件流的原因。如果你允许异步并发消息传递,无论如何它会变得复杂得多。

标签: javascript jquery asynchronous iframe


【解决方案1】:

感谢 Bergi 的评论,我能够将其转换为 Promise。

factoryMethod(msgIn, msgOut) {                                                                                                                                                                                  
  return (ann)  => new Promise((resolve, reject) => {                        
    this.post(msgIn, ann);                                                                                                                                                                                      
    $(window).on(msgOut, (e, arg) => resolve(arg));                                                                                                           
  });                                                                                                                                                                                                           
}    

这会返回一个返回 Promise 的高阶函数。

【讨论】:

    【解决方案2】:

    也许已经回答了,但我通常是这样回答的:

    // given you've defined this `Future` fn somewhere:
    const Future = fn => {return new Promise((r,t) => fn(r,t))}
    
    // define an eventFn that takes a promise `resolver`
    const eventFn = resolve => {
      // do event related closure actions here. When finally done, call `resolve()`
      something.oneventfired = e => {resolve(e)}
    }
    
    // invoke eventFn in an `async` workflowFn using `Future`
    // to obtain a `promise` wrapper
    const workflowFn = async () => {await Future(eventFn)}
    

    特别是像 indexedDb 事件包装器这样的东西,以简化使用。

    或者您可能会发现Future 的这种变体更通用

    class PromiseEx extends Promise {
      resolve(v,...a) {
        this.settled = true; this.settledValue = v;
        return(this.resolve_(v,...a))
      }
      reject(v,...a) {
        this.settled = false; this.settledValue = v;
        return(this.reject_(v,...a))
      }
      static Future(fn,...args) {
        let r,t,ft = new PromiseEx((r_,t_) => {r=r_;t=t_})
        ft.resolve_ = r; ft.reject_ = t; fn(ft,...args);
        return(ft)
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-12
      • 2023-04-08
      • 1970-01-01
      相关资源
      最近更新 更多