Preserve the order of the http calls in angular

China☆狼群 提交于 2019-12-01 10:48:55

Since the http-calls are asynchronous, the responses may not arrive in the same order the requests were made. What you could do is to create a list of requests, create a forkJoin and wait for all responses to resolve. You can then call the displayNewTileLayer(dimensions)-method for all responses.

Here is an example

    const httpCalls = []; // store the requests here
    for (let i = 0; i < 3; i++) {
      httpCalls.push(this.http.get('someUrl').map(response => response));
    }
    forkJoin(httpCalls).subscribe(res => {
      // all responses completed. returns an array of data (one for each response).
      console.log('res', res);
    });

In you case, this code may work: (code not tested, and you may have to import the forkJoin operator in your code)

import { forkJoin } from 'rxjs/observable/forkJoin';

private loadSelectedTileLayersCapabilities(): void {

    let tempTileLayer;
    let requests = []:

    this.selectedTileLayerIds.forEach(
        (selectedTileLayer: string) => {
            tempTileLayer = this.getTileLayerById(selectedTileLayer);
            const request = this.capabilitiesService.getTileLayerDimensions(tempTileLayer.url, tempTileLayer.name, tempTileLayer.id)
            requests.push(request);

        }
    );
    forkJoin(requests).subscribe(res => {
      res.forEach(dimension => this.displayNewTileLayer(dimension));
    })
}

I would consider to use the concat operator.

Your code would look like the following

    private loadSelectedTileLayersCapabilities(): void {

            let tempTileLayer;
            let concatObs;

            this.selectedTileLayerIds.forEach(
                (selectedTileLayer: string) => {
                    tempTileLayer = this.getTileLayerById(selectedTileLayer);

                    const httpCall = this.capabilitiesService.getTileLayerDimensions(tempTileLayer.url, tempTileLayer.name, tempTileLayer.id);
                    if (!concatObs) {
                        concatObs = httpCall);
                     } else {
                         concatObs.concat(httpCall);
                     }

                }
            );
            concatObs.subscribe(
                dimensions => this.displayNewTileLayer(dimensions)
            );
        }

This way concatObs emits in the same order as the array selectedTileLayersIds. You should consider though if it is possible to move the sequencing logic to the server, i.e. have a service that receives an array of ids (selectedTileLayersIds) and returns and array of dimensions. In this way you would reduce the network traffic and avoid having a chain of sequential synchronous http calls.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!