在角度项目中使用 rxjs 进行 http 轮询和条件逻辑



我正处于 Angular 4 项目的早期阶段,试图为我的 http 服务创建一个客户端。这些服务可以返回以下两项内容之一:

  1. 来自 http 状态为 200 的服务的实际所需 json 响应,或
  2. 一个
  3. guid,表示一个作业令牌,我可以使用该令牌轮询长时间运行的作业的状态,以及 http 状态 202。

当服务返回 200 状态时,我只想直接返回其 json 内容,因此这很容易。

当结果状态为 202 时,我想使用该令牌轮询一个单独的 url,并接收一个包含状态信息的 json 对象。 当该状态信息指示完成时,我想向将返回输出的最终网址发出请求。

我不确定如何处理请求中需要的条件逻辑。我怀疑我可以使用repeatWhen来监视轮询请求的结果,但我无法弄清楚如何使用它。

http.request('/some/longrunning/job')
.flatMap((resp: Response) => {
if (resp.status !== 202)
return Observable.of(resp);
var job_token = resp.json().token;
return http.get('/jobstatus/' + job_token)
// result from this endpoint is a json object that looks something
// like { status: 'running' } or { status: 'complete' }
.repeatWhen(function (polling_resp: Observable<Response>) {
// How do I use polling_resp here to look at my http response?
// Do I need to explicitly subscribe to it? And if so,
// how then do I inspect the response and return the
// appropriate value to indicate whether or not to
// resubscribe via the repeatWhen?
});
});

有人可以给我一些关于如何在repeatWhen中使用逻辑的提示吗?我还没有看到任何使用可观察量本身的内容来决定是否重新订阅的示例。

我认为您正在寻找更像这样的东西:

http.request('/some/longrunning/job')
.flatMap((resp: Response) => {
if (resp.status !== 202)
return Observable.of(resp);
const token = resp.json().token;
return http.get(`/jobstatus/${token}`)
// You can use repeatWhen if you need more nuanced logic for
// how many times you want this to repeat, and how it should 
// space out repeat attempts.
// This is just an example that guarantees at least 1 second between
// poll attempts so as to not overload the server
.repeatWhen(c => c.debounceTime(1000))
// Ignore values until you have completed
.skipWhile(resp => resp.json().status !== 'completed')
// At this point you can stop the polling
.take(1)
// You don't actually care about the value of the response
// just that it has "completed" this maps that response to the
// call to fetch the result status.
.flatMapTo(http.get(`/jobresult/${token}`))
});

本质上,您的第一个条件是正确的,第二部分您需要启动请求并不断重复它,skipWhile部分将检查结果并且在状态标记为完成之前不会传播它们,然后您可以使用flatMapTo将该结果消息直接转换为另一个 API 请求以获得实际结果,然后传播。

最新更新