簡體   English   中英

在rxjs / angular中動態鏈接Observable

[英]Dynamically chaining Observables in rxjs / angular

我遇到的情況是我可能從一個對象觸發多個事件。 這些事件在組件中處理,然后發送到REST API。 但是,我需要確保按順序發送對特定資源的REST api的調用。 所以可以說我有以下方法:

someObjectCreated(objectCreated){
    this.http.post(...);
}

someObjectNameChanged(objectNameChanged){
    this.http.post(...);
}

someObjectDeleted(objectDeleted){
    this.http.delete(...);
}

這些事件處理程序方法可以隨時調用。 可以說我有一個場景,其中調用someObjectCreated,然后在someObjectCreated的POST返回之前,立即調用someObjectNameChanged。

有什么辦法可以將這些可觀察的結果鏈接起來? 我是否最好將它們轉換為Promise,然后繼續將它們與.then()鏈接起來? 在Angular中是否有一些常用的模式可以做到這一點?

您可以使用Observable.flatMap運算符。可以通過這種方式實現。

this.service.someObjectCreated(objectCreated)
    .flatMap(objectNameChanged=> this.service.someObjectNameChanged(objectNameChanged))
    .flatMap(secondMethodResult => this.service.someObjectDeleted(secondMethodResult ))
    .subscribe(thirdMethodResult => {
          console.log(thirdMethodResult);
     });

我認為您必須將loader放在發送的任何請求之前,並在完成並根據響應更新對象后將其刪除,因為如果在到達第一個響應之前用相同的對象觸發了第二個請求,那么您將丟失原始數據。

我認為這與RxJS無關,您是對的。 您可以簡單地將所需操作與承諾聯系在一起。 您可以為此創建一些通用的函數/類(沒有錯誤處理,只是給您一個想法):

class QueuedActions {

    private currentlyRunning: Promise<void> = Promise.resolve();

    public submit(task: () => Promise<void>): Promise<void> {
       const prevActionPromise = this.currentlyRunning;
       // substitute current promise for next call
       this.currentlyRunning = new Promise<void>(async (resolve, reject) => {
            // wait for previous actions to finish
            await prevActionPromise;
            // perform submitted task
            await task();
            // resolve current promise, so next action can go ahead
            resolve();
        });
        return this.currentlyRunning;
    }

}

因此,如果需要,您可以鏈接任何返回promise的函數:

someObjectCreated(objectCreated){
    this.queuedActions.submit(() => this.http.post(...));
}

someObjectNameChanged(objectNameChanged){
    this.queuedActions.submit(() => this.http.post(...));
}

像這樣嘗試鏈方法flatMap()

this.service.someObjectCreated(queryParam)
    .flatMap((someObjCreatedRsp) => {
        console.log('someObjCreatedRsp', someObjCreatedRsp);
        return this.service.someObjectNameChanged(queryParam)
    })
    .flatMap((someObjNameChangedRsp) => {
        console.log('someObjNameChangedRsp', someObjNameChangedRsp);
        return this.service.someObjectDeleted(queryParam)
    })
    .subscribe((someObjDeletedRsp) => {
        console.log('someObjDeletedRsp', someObjDeletedRsp);
    });

暫無
暫無

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

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