【问题标题】:Http polling and conditional logic with rxjs in angular projectAngular项目中使用rxjs的Http轮询和条件逻辑
【发布时间】:2017-08-08 19:31:38
【问题描述】:

我正处于尝试为我的 http 服务创建客户端的 Angular 4 项目的早期阶段。这些服务可以返回以下两种情况之一:

  1. http 状态为 200 的服务的实际所需 json 响应,或
  2. 代表作业令牌的 guid,我可以使用它轮询长期运行作业的状态和 202 的 http 状态。

当服务返回 200 状态时,我想直接返回它的 json 内容,这样就很简单了。

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

我不确定如何处理请求中所需的条件逻辑。我怀疑我可以使用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 中使用逻辑的提示吗?我还没有看到任何使用 observable 本身的内容来决定是否重新订阅的示例。

【问题讨论】:

    标签: angular rxjs observable


    【解决方案1】:

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

    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 请求以获取 实际 结果,然后传播该结果。

    【讨论】:

      猜你喜欢
      • 2018-03-18
      • 2016-05-02
      • 2018-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-05
      • 2016-12-31
      • 2018-10-08
      相关资源
      最近更新 更多