簡體   English   中英

如何多次解決一個承諾?

[英]How to resolve a promise multiple times?

這聽起來可能很奇怪,但我正在尋找一種方法來多次解決承諾。 是否有任何方法可以使這成為可能?

想想下面的例子:

getPromise() {
  const event = new Event('myEvent');

  setTimeout(() => {
    window.dispatchEvent(event);
  }, 5000);

  setTimeout(() => {
    window.dispatchEvent(event);
  }, 7000);

  return new Promise((resolve) => {
    window.addEventListener('myEvent', () => {
      resolve('some value'));
    });

    resolve('some value'));
  });
};

然后.then():

getPromise().then(data => {console.log(data)})

應該給出以下結果:

some value // initial
some value // after 5000ms
some value // after 7000ms

所以我知道有一些庫可以傳輸數據,但我真的在尋找一種本機非回調方法來實現這一點。

如何多次解決一個承諾?

你不能。 Promises 只能被解決一次。 一旦它們得到解決,它們就永遠不會再改變它們的狀態。 它們本質上是一種單向狀態機,具有掛起、完成和拒絕三種可能的狀態。 一旦它們從待處理變為已完成或從待處理變為拒絕,它們就無法更改。

因此,您幾乎不能也不應該將 Promise 用於您想要多次發生的事情。 對於類似的事情,事件偵聽器或觀察器比 promise 更匹配。 您的承諾只會通知您它收到的第一個事件。

我不知道你為什么在這種情況下試圖避免回調。 Promise 在其.then()處理程序中也使用回調。 您將需要在某處進行回調以使您的解決方案起作用。 你能解釋一下為什么你不直接使用window.addEventListener('myEvent', someCallback) ,因為這會做你想要的嗎?


您可以返回一個類似 Promise 的接口(不遵循 Promise 標准),它會多次調用其通知回調。 為了避免與 promise 混淆,我不會使用.then()作為方法名稱:

 function getNotifier() { const event = new Event('myEvent'); setTimeout(() => { window.dispatchEvent(event); }, 500); setTimeout(() => { window.dispatchEvent(event); }, 700); let callbackList = []; const notifier = { notify: function(fn) { callbackList.push(fn); } }; window.addEventListener('myEvent', (data) => { // call all registered callbacks for (let cb of callbackList) { cb(data); } }); return notifier; }; // Usage: getNotifier().notify(data => {console.log(data.type)})

我在打字稿中有一個解決方案。

export class PromiseParty {
  private promise: Promise<string>;
  private resolver: (value?: string | PromiseLike<string>) => void;
  public getPromise(): Promise<string> {
     if (!this.promise) {
        this.promise = new Promise((newResolver) => { this.resolver = newResolver; });
     }
        return this.promise;
   }
   public setPromise(value: string) {
      if(this.resolver) {
         this.resolver(value);
         this.promise = null;
         this.resolver = null;
      }
   }
}

export class UseThePromise {
   public constructor(
       private promiseParty: PromiseParty
   ){
      this.init();
   }
   private async init(){
      const subscribe = () => {
         const result = await this.promiseParty.getPromise();
         console.log(result);
         subscribe(); //resubscribe!!
      }
      subscribe(); //To start the subscribe the first time
   }  
}


export class FeedThePromise {
   public constructor(
      private promiseParty: PromiseParty
   ){
        setTimeout(() => {
           this.promiseParty.setPromise("Hello");
        }, 1000);
        setTimeout(() => {
           this.promiseParty.setPromise("Hello again!");
        }, 2000);

        setTimeout(() => {
           this.promiseParty.setPromise("Hello again and again!");
        }, 3000);
    }
 }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM