typescript RxJS和类型ORM:使用iif()不受控制地保存对象

rsl1atfo  于 2023-03-13  发布在  TypeScript
关注(0)|答案(1)|浏览(123)

我正在为一个ORM实体实现findOrSave方法,并希望使用rxjs函数concatMap和iif来合并观察值。
然而,不知何故,我的代码不起作用:

return from(this.repository.findOne({ where: { label: ILike('%' + title + '%') } })).pipe(concatMap(ge => {
  return iif(() => !!ge, of(ge), from(this.repository.save({label: title})));
}))

我有一个非键但唯一的值(如label),并希望使用findOne检索实体。如果findOne返回实体,则应将其返回。否则,应保存该实体并返回存储的实体。
虽然findOne看起来工作得很完美,但不知何故,即使iif的第一个参数返回false,也会调用保存方法。
我不能真正理解这一点,因为下面的片段是有效的:

return from(this.repository.findOne({ where: { label: ILike('%' + title + '%') } })).pipe(concatMap(ge => {
            return iif(() => !!ge, of(ge), new Observable<GreaterEntity>(subs => {
                from(this.repository.save({label:title})).subscribe(v => {
                    console.log('Saving id '+v.id)
                    subs.next(v);
                })
            }));
        }))

如果有人能指出我犯的错误,我会非常感激的:)

brtdzjyr

brtdzjyr1#

问题是当我们调用iif时,你传递了from(this.repository.save({label: title})),这会立即调用this.repository.save(),而不需要等待任何订阅。
要避免这种情况,可以使用defer

from(
  this.repository.findOne({ where: { label: ILike('%' + title + '%') } })
).pipe(
  concatMap(ge => iif(
    () => !!ge, 
    of(ge), 
    defer(() => from(this.repository.save({label: title})))
  ))
)

defer中的回调仅在有东西订阅它时才被调用。

相关问题