在RxJS 6管道中使用forkJoin作为可允许的运算符

时间:2019-05-29 14:05:43

标签: rxjs6

最终目标
我有一个用户/设备注册方法。在其中,我需要:

  1. 检查本地存储是否已就绪
  2. 如果是这样,请分别检查deviceId和令牌
  3. 如果找不到deviceId或令牌,请致电注册端点

我在哪里
在构建过程中,为了简化起见,我没有处理令牌化。我只使用deviceId,下面的方法可以正常工作。

我调用了isStorageReady帮助器方法,检查了响应,然后调用了getDeviceId帮助器方法,并检查了该响应。

this.isStorageReadyAsync()
    .pipe(
        map(storageResponse => {
            // check storageResponse
            // if undefined throw error
            // error picked up by retryPipeline
            // if retryPipeline exhausted picked up 
            // by errorPipeline and stream is stopped
            if (storageRes === undefined ||
                storageRes['LOCALSTORAGE'] === undefined ||
                storageRes['LOCALSTORAGE'] === '') throw 'storageRes or 
                storageRes.LOCALSTORAGE are undefined or empty';
        }),
        flatMap(_ => this.getStoredDeviceIdAsync()),
        map(deviceId => {
            return iif(() => deviceId === undefined || 
                             deviceId === null || 
                             deviceId === '',
                       // no deviceId stored on device
                       // register device to get deviceId
                       this.registerDeviceAsync(), 
                       // deviceId found in local storage
                       of({id: deviceId, new: false}))
        }),
        this.storeDeviceIdPipeline, // store deviceId
        this.retryPipeline, // retry if e.g. experiencing network issues
        this.errorPipeline // catch and handle errors
    )

我被困在哪里
我有第二个辅助方法getStoredTokenAsync(),我想与getStoredDeviceIdAsync()并行调用。我尝试使用forkJoin并将数组传递到随后的map运算符中,但是我的打字稿夹棉布一点都不喜欢。对forkJoin之前的所有内容都加下划线,就好像是一个错误,并且该错误的内容如下:

  

OperatorFunction类型的参数不能分配给OperatorFunction类型的参数。无效类型不能分配给{}。

所以我不太明白。我希望使用这样的东西:

...
forkJoin([this.getStoredDeviceIdAsync(), this.getStoredTokenAsync()]),
map(authArr => {
   let deviceId = authArr[0];
   let token = authArr[1];
   ...
})
...

1 个答案:

答案 0 :(得分:0)

感谢LookForAngular和JuliusDzidzevičius这两个评论者共同帮助完成了这些工作!在此提供完整答案,以防对他人有所帮助。还提供了一些其他上下文的更多代码。

mergeMapTo调用之前,需要进行一些常规的响应检查。该输出不会被消耗,因此使用mergeMapTo是适当的(这意味着之前发生的任何事情与mergeMapTo内部发生的事情无关)。

mergeMap基本上使内部的可观察性变平,这由我的iif调用提供。 mergeMap的输出被路由到我的存储管道(这只是一个map调用),该管道处理与用户身份验证等相关的所有逻辑。

pipe(
    ...
    mergeMapTo(forkJoin([this.getStoredDeviceIdAsync(), this.getStoredTokenAsync()])),
    mergeMap(authArr => {
        let deviceId = authArr[0];
        let token = authArr[1];
        return iif(() => deviceId === undefined || deviceId === null || deviceId === '' ||
                         token === undefined || token === null || token === '',
                         this.registerDeviceAsync(), // register device to get deviceId and token
                         of({deviceId: deviceId, token: token, new: false})) 
    }),
    this.storeDeviceIdTokenPipeline,
    this._config.retryPipeline, // generic retryWhen procedure
    this._config.errorPipeline // generic catchError procedure
)