RxJS:使用shareReplay发布HTTP请求一次,然后使用返回的ID来更新队列

RxJS:使用shareReplay发布HTTP请求一次,然后使用返回的ID来更新队列,rxjs,Rxjs,基本上,我需要: const saveObservable = new Subject().asObservable(); const create$ = of("ID").pipe(tap(() => console.log("executed")), shareReplay()); const subscription = saveObservable.pipe( concatMap(({ files = [], ...attributes }) => create

基本上,我需要:

const saveObservable = new Subject().asObservable();
const create$ = of("ID").pipe(tap(() => console.log("executed")), shareReplay());

const subscription = saveObservable.pipe(
  concatMap(({ files = [], ...attributes }) =>
    create$.pipe(
      tap(id => console.log("queue updates to", id))
    )
  )
).subscribe();

saveObservable.next({})
这将使我的初始保存操作:
of(“ID”)
只执行一次。然后,此保存的所有后续执行将使用返回的ID并排队

我正在努力解决的是,我不能将
create$
放入我的
concatMap
中,因为它创建了一个新的可观察实例,而
shareReplay
实际上是无用的

但是我基本上需要在
concatMap
中使用它,这样我就可以使用
属性了

我该怎么做

saveObservable.pipe(
  concatMap(({ files = [], ...attributes }) => {
    const create$ = fromFetch("https://www.google.com", { attributes }).pipe(tap(() => console.log("executed")), shareReplay());

    return create$.pipe(
      tap(a => console.log(a))
    )
  })
);
vs


不确定这是否是最好的方法,但我想到的是

您可以将
ReplaySubject
用作订户。当以这种方式使用时,它将缓存从源发出的值

所以你可以有这样的东西:

const replsub=新的ReplaySubject(/*…*/);
救生衣(
concatMap(({files=[],…attributes})=>{
//我们首先订阅'replsub',以便获得存储的值
//如果没有一个存储的符合“first”中施加的条件,
//只需发出`of({key:null})`,这意味着将发出请求
返回合并(replsub,of({key:null}))
.烟斗(
//检查之前是否有具有此类属性的请求
//如果是:只返回从主题接收到的存储值
//如果不是:发出请求并存储值
//通过使用'first',我们还可以确保主题不会有多余的订阅者
首先(v=>v.key==attributes.identifier | | v.key==null),
开关图(
v=>v.key==null
?fromFetch(“https://www.google.com管道(点击(()=>console.log(“已执行”))
.烟斗(
map(response=>({key:attributes.identifer,response})),//添加键以便我们以后可以区分它
点击({response})=>replsub.next(response))//将值存储在主题中
)
:of(v.response)//立即发出并完成
),
)
}),
);

请注意,
ReplaySubject
可以有第二个参数,
windowTime
,它指定值应缓存多长时间。

不确定这是否是最佳方法,但我想到的是

您可以将
ReplaySubject
用作订户。当以这种方式使用时,它将缓存从源发出的值

所以你可以有这样的东西:

const replsub=新的ReplaySubject(/*…*/);
救生衣(
concatMap(({files=[],…attributes})=>{
//我们首先订阅'replsub',以便获得存储的值
//如果没有一个存储的符合“first”中施加的条件,
//只需发出`of({key:null})`,这意味着将发出请求
返回合并(replsub,of({key:null}))
.烟斗(
//检查之前是否有具有此类属性的请求
//如果是:只返回从主题接收到的存储值
//如果不是:发出请求并存储值
//通过使用'first',我们还可以确保主题不会有多余的订阅者
首先(v=>v.key==attributes.identifier | | v.key==null),
开关图(
v=>v.key==null
?fromFetch(“https://www.google.com管道(点击(()=>console.log(“已执行”))
.烟斗(
map(response=>({key:attributes.identifer,response})),//添加键以便我们以后可以区分它
点击({response})=>replsub.next(response))//将值存储在主题中
)
:of(v.response)//立即发出并完成
),
)
}),
);
请注意,
ReplaySubject
可以有第二个参数,
windowTime
,它指定值应该缓存多长时间。

我用以下方法解决了这个问题:

  let create$: Observable<EnvelopeSummary>;

  const [, , done] = useObservable(
    updateObservable$.pipe(
      concatMap(attributes => {
        if (create$) {
          return create$.pipe(
            concatMap(({ envelopeId }) =>
              updateEnvelope({ ...userInfo, envelopeId, attributes }).pipe(
                mapTo(attributes.status)
              )
            )
          )
        } else {
          create$ = createEnvelope({ ...userInfo, attributes }).pipe(
            shareReplay()
          );
          return create$.pipe(mapTo(attributes.status))
        }
      }),
      takeWhile(status => status !== "sent")
    )
  );
create$:可观察;
常数[完成]=可用可观察(
updateObservable$.pipe(
concatMap(属性=>{
如果(创建$){
返回创建$.pipe(
concatMap({envelopeId})=>
UpdateDevelope({…userInfo,envelopeId,attributes}).pipe(
映射到(attributes.status)
)
)
)
}否则{
create$=createEnvelope({…userInfo,attributes})。管道(
shareReplay()
);
返回create$.pipe(映射到(attributes.status))
}
}),
takeWhile(状态=>状态!==“已发送”)
)
);
我用以下方法解决了这个问题:

  let create$: Observable<EnvelopeSummary>;

  const [, , done] = useObservable(
    updateObservable$.pipe(
      concatMap(attributes => {
        if (create$) {
          return create$.pipe(
            concatMap(({ envelopeId }) =>
              updateEnvelope({ ...userInfo, envelopeId, attributes }).pipe(
                mapTo(attributes.status)
              )
            )
          )
        } else {
          create$ = createEnvelope({ ...userInfo, attributes }).pipe(
            shareReplay()
          );
          return create$.pipe(mapTo(attributes.status))
        }
      }),
      takeWhile(status => status !== "sent")
    )
  );
create$:可观察;
常数[完成]=可用可观察(
updateObservable$.pipe(
concatMap(属性=>{
如果(创建$){
返回创建$.pipe(
concatMap({envelopeId})=>
UpdateDevelope({…userInfo,envelopeId,attributes}).pipe(
映射到(attributes.status)
)
)
)
}否则{
create$=createEnvelope({…userInfo,attributes})。管道(
shareReplay()
);
返回create$.pipe(映射到(attributes.status))
}
}),
takeWhile(状态=>状态!==“已发送”)
)
);

create$是一个http调用,还是只是为了保存id以便共享?这是一个http调用。这就是我需要传递给主题的属性:
fromFetch(…,attributes)