在rxjs / angular中动态链接Observable

时间:2017-11-28 03:39:25

标签: angular typescript rxjs angular2-observables

我遇到的情况是我有多个可能从对象触发的事件。这些事件在组件中处理,并发送到REST API。但是,我需要确保针对特定资源的REST api的调用是串行发送的。所以我要说我有以下方法:

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

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

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

可以随时调用这些事件处理程序方法。假设我有调用someObjectCreated的场景,然后在someObjectCreated的POST返回之前立即调用someObjectNameChanged。

有没有办法可以将这些观察结果链接起来?我最好将这些转换为承诺,然后用.then()不断链接它们吗?是否在Angular中使用了一些常见的模式来实现这一目标?

2 个答案:

答案 0 :(得分:0)

我认为这与RxJS无关,你是对的。您可以使用promises链接所需的操作。你可以为此创建一些通用函数/类(没有错误处理,只是给你一个想法):

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(...));
}

答案 1 :(得分:0)

尝试这种方式链式方法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);
    });