轮询具有依赖关系的http服务

时间:2017-11-06 18:29:24

标签: angular observable

所以,我已经按照这个问题的答案: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”。但它们都发生过多次。

好的......事实证明我没有仔细看待我的回答。

**中等成功的更新** Constants.COMPLETE =“COMPLETE”

statusCode给了我“COMPLETED”。

一旦我解决了这个问题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",
}

1 个答案:

答案 0 :(得分:0)

好的......事实证明我没有仔细看待我的回答。

Constants.COMPLETE =“COMPLETE”

statusCode给了我“COMPLETED”。

一旦我解决了这个问题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);
    });