问题
for (let i = 0; i < this.data.VirtualHosts.length; i++) {
// get the vh
this.apiService.findVH(this.data.VirtualHosts[i])
// then add each vhost to data by concat and then convert to json
.subscribe((data) => {
this.data = data.docs[0]
this.jsonData = this.jsonData.concat(this.data)
//console.log("AFTER: " + this.jsonData[i]._id)
//console.log("Response for getVH: " + JSON.stringify(this.jsonData))
})
}
Here, I loop through a list of ID's of VirtualHosts and do a get call (findVH) on every single one of them. However, the get call seems to be calling each index out of order. How would I make it so that the get call returns a list of data in the order that it was given in the this.data.VirtualHosts list?
回答1:
I think you will need to do 2 things. One convert your this.data.VirtualHosts into an observable using the from operator as described here:
https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/from.md
Then use concatMap which will force the api results to return in the order that you are firing off the requests. This is explained here:
https://www.learnrxjs.io/operators/transformation/concatmap.html
回答2:
I wouldn't recommend to use an observable inside a loop unless you really have to.. consider get all of your data within one api call / observable. If you are not unsubscribing from each one of the observables you will end up with a memory leak (unless you are using angular http).
Anyway, try wrap your code with a timeout to add it to the event queue:
for (let i = 0; i < this.data.VirtualHosts.length; i++) {
setTimeout(() => {
// get the vh
this.apiService.findVH(this.data.VirtualHosts[i])
// then add each vhost to data by concat and then convert to json
.subscribe((data) => {
this.data = data.docs[0]
this.jsonData = this.jsonData.concat(this.data)
//console.log("AFTER: " + this.jsonData[i]._id)
//console.log("Response for getVH: " + JSON.stringify(this.jsonData))
})
}, 0);
}
Currently the for loop ends before your service method is being exeucuted.
回答3:
The return values are in an incorrect order mainly due to the fact that Observables
will create a separate thread per call therefore the loop completes before the result arrives; this is why unordered list. What I done in this kind of situation is to put that in a method, store the unordered list and then filter the result to another variable by running a something like find
or filter
method to use common value from this.data.virtualHosts
and the unordered result to put them back to order.
来源:https://stackoverflow.com/questions/44974036/angular2-observable-getting-data-from-list-out-of-order