javascript - Bir tetikleyici/olayı nasıl Promise veya async/await'e çevirebilirim?


Bir callback fonksiyonunu async/await'e dönüştürmeye çalışıyorum. Kod, ana pencere çerçevesinden bir iframe'e postMessage kullanıyor. iframe bir mesaj geri gönderdiğinde, callback fonksiyonunu çağırıyor. $ (window).on(...) deseninden Promise'a geçmenin bir yolu var mı?

Çalışan kodun minimal versiyonu:

Fonksiyonu çağırmak için:

window.bridge.post(cb);

Köprü nesnesi:

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;

Şimdiden teşekkürler.

Cevap #1

Bergi'nin yorumu sayesinde bunu Promise'e dönüştürebiliyorum.

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

Bu, bir Promise döndüren yüksek dereceli bir fonksiyon döndürür.

Cevap #2

Belki zaten cevaplanmış olabilir, ama ben bunu genellikle şöyle yaparım:

// 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)}

Özellikle kullanımını basitleştirmek için indexedDb olay sarmalayıcıları gibi şeyler için.

Ya da bu Future varyasyonunu daha genel amaçlı bulabilirsiniz

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)
  }
}