【问题标题】:Polling an http service with dependencies轮询具有依赖项的 http 服务
【发布时间】:2017-11-06 18:29:24
【问题描述】:

所以,我遵循了这个问题的答案:Long Polling in Angular 4 但我仍然有问题。

我需要调用和轮询的端点需要来自对另一个端点的调用的数据。所以我有以下内容:

return this.postJob(ids)
    .flatMap(postRes => {
        return Observable
            .interval(250)
            .switchMap(() => { 
                console.log("POSTRES: " + JSON.stringify(postRes, null, 2); 
                return this.getJob(postRes.id);
            })
            .map(getRes => getRes)
            .takeWhile(getRes => {
                console.log("GETRES: " + JSON.stringify(getRes, null, 2); 
                return getRes.statusCode !== Constants.COMPLETE;
            })
            .catch(SharedHttpMethods.handleError);
    });

我称之为:

processJob(ids).subscribe(jobRes => { 
    console.log("downloadSelected: ", JSON.stringify(jobRes, null, 2)); 
    // act on the completed response 
});

我遇到的问题是 postJobs 服务被一遍又一遍地调用。 .takeWhile 永远不会终止订阅。我认为 flatMap 可能与此有关,但我不确定。

有什么建议可以解决这个问题吗?

注意事项: postJob 和 getJob 返回相同的 json 对象模型。但是,getJob 取决于从 postJobs 调用返回的 id。

当我运行当前代码时,我可以看到“QUEUED”、“PROCESSING”,最后是“COMPLETED”。但它们都会发生多次。

好吧...事实证明我没有仔细查看我的回复。

** 更新成功率中等 ** 常量.COMPLETE = "完成"

statusCode 显示“已完成”。

一旦我解决了这个问题,getRes.statusCode !== Constants.COMPLETED,一切正常。

但是我遇到了一个新问题。一旦.takeWhile 得到一个错误的声明,它就会停止 Observable。但它不会将最终的 COMPLETED 对象传回。

所以,我明白了

GETRES: ... QUEUED
downloadSelected: ... QUEUED
GETRES: ... COMPLETED

但我没有收到downloadSelected: ... COMPLETED。 我错过了什么

输出:

"POSTJOB":  {
  "_links": {
    "self": {
      "href": "http://localhost:9000/api/v1/jobs/44"
    }
  },
  "id": 44,
  "statusCode": "QUEUED",
}
"GETJOB":  {
 "_links": {
    "self": {
      "href": "http://localhost:9000/api/v1/jobs/44"
    }
  },
  "id": 44,
  "statusCode": "QUEUED",
}
"downloadSelected": {
  "_links": {
    "self": {
      "href": "http://localhost:9000/api/v1/jobs/44"
    }
  },
  "id": 44,
  "statusCode": "QUEUED",
}
"POSTJOB":  {
  "_links": {
    "self": {
      "href": "http://localhost:9000/api/v1/jobs/44"
    }
  },
  "id": 44,
  "statusCode": "QUEUED",
}
"GETJOB":  {
  "_links": {
    "self": {
      "href": "http://localhost:9000/api/v1/jobs/44"
    }
  },
  "id": 44,
  "statusCode": "PROCESSING",
}
"downloadSelected": {
  "_links": {
    "self": {
      "href": "http://localhost:9000/api/v1/jobs/44"
    }
  },
  "id": 44,
  "statusCode": "PROCESSING",
}
"POSTJOB":  {
  "_links": {
    "self": {
      "href": "http://localhost:9000/api/v1/jobs/44"
    }
  },
  "id": 44,
  "statusCode": "QUEUED",
}
"GETJOB":  {
  "_links": {
    "self": {
      "href": "http://localhost:9000/api/v1/jobs/44"
    },
    "zip": {
      "href": "linkToZipFile"
    }
  },
  "id": 44,
  "statusCode": "COMPLETED",
}

【问题讨论】:

  • flatMap 是否如您所愿?
  • 据我所知。我在上面没有重复的代码中有几个控制台记录器,它告诉我postJobgetJob 调用都在工作并返回正确的数据。第一个回复显示{ id: 44, _links: { self: { href: "http://localhost:9000/api/v1/jobs/44" } }, statusCode: "QUEUED" },稍后给我:{ id: 44, _links: { self: { href: "http://localhost:9000/api/v1/jobs/44" }, zip: { href: "linkToZipFile"} }, statusCode: "COMPLETED" }
  • 我的猜测是你的 takeWhile 只是完成了外部 observable。尝试将其添加到您的 switchMap return this.getJob(postRes.id).takeWhile(...) 中的内部 observable
  • 在阅读了有关 takeWhile 的更多信息后,我上面的评论没有意义:/ 你说 .takeWhile never kills the subscription。你的意思是你得到2个COMPLETED的发射?或者可观察的序列永远不会停止并无限期地运行?

标签: angular observable


【解决方案1】:

好吧...事实证明我没有仔细查看我的回复。

Constants.COMPLETE = "完成"

statusCode 显示“已完成”。

一旦我解决了这个问题,getRes.statusCode !== Constants.COMPLETED,一切正常。

对于那些正在寻找有关如何在使用.takeWhile 时进行多次通话的答案的人,答案就在问题中。我需要在 statusCode==COMPLETED 时返回的第一个对象,但除了第一个之外不需要任何东西。 .takeWhile 在 COMPLETED 之前返回所有内容。 .skipWhile 返回第一个 COMPLETED 和之后的所有内容。 .take(1).skipWhile 限制为一次调用。

我需要的答案如下。它利用.skipWhile.take

return this.postJob(ids)
    .flatMap(postRes => {
        return Observable
            .interval(250)
            .switchMap(() => { 
                console.log("POSTRES: " + JSON.stringify(postRes, null, 2); 
                return this.getJob(postRes.id);
            })
            .map(getRes => getRes)
            .skipWhile(getRes => {
                console.log("GETRES: " + JSON.stringify(getRes, null, 2); 
                return getRes.statusCode !== Constants.COMPLETE;
            })
            .take(1)
            .catch(SharedHttpMethods.handleError);
    });

【讨论】:

    猜你喜欢
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 2012-07-06
    • 2021-08-15
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    相关资源
    最近更新 更多