WMS 迭代 getFeatureInfo URL 数组以获取响应随机化接收值的顺序

WMS Iterating through an Array of getFeatureInfo URLs to fetch the response randomizes the order of received values

背景: 使用 Openlayers 和 Geoserver,我得到了一个如下图所示的 WMS 层,它有两个不同的视图参数,可以分别取 5 和 7 个值。结合这两者,我总共可以获得 35 个不同的值。我想实现一个函数,当您单击一个国家/地区时,用所有这些值(7 行,5 列)填充 table。 WMS Layer

为此,我首先生成一个包含 35 个唯一 getFeatureInfo 网址的数组,如下所示 http://localhost:8080/geoserver/abschluss/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetFeatureInfo&FORMAT=image%2Fpng&TRANSPARENT=true&QUERY_LAYERS=abschluss&LAYERS=abschluss&TILED=true&CRS=EPSG%3A3857&VIEWPARAMS=year%3A2000%3Bcode%3A1&INFO_FORMAT=application%2Fjson&I=106&J=72&WIDTH=256&HEIGHT=256&STYLES=&BBOX=0%2C5009377.085697312%2C2504688.5428486555 %2C7514065.628545968 使用 for 循环和 url.replace 函数。然而,这不是问题。

let value = [];
for (i = 0; i<5; i++) {
  const url = urlArray[i];
  if (url) {
    fetch(url)
      .then((response) => response.text())
      .then((jsonResponse) => {
        const jsonObject = JSON.parse(jsonResponse);
        value.push(jsonObject.features[0].properties.year);
        
      });
  } 

}

有了这个,我想遍历我的 urlArray 的前 5 个元素,将响应作为 JSON 对象获取,提取所需的值并将它们写入一个新数组,然后用于在 HTML table 中填写一行。 使用 console.log(值);我可以看到这确实给了我想要的值,但是顺序似乎是随机的。每次我点击国家时,顺序都会完全改变。 为什么会发生这种情况,我该怎么做才能解决这个问题?

为了让您更好地理解,我将整个函数按原样包含在内:

map.on('singleclick', function (evt) {
document.getElementById('gfi').innerHTML = '';
const viewResolution = /** @type {number} */ (view.getResolution());
var url = sourceValues.getFeatureInfoUrl(
  evt.coordinate,
  viewResolution,
  'EPSG:3857',
  {'INFO_FORMAT': 'application/json'},
  {'VIEWPARAMS': 'code:1;year:1990'}
);

let yearArray = [1995,2000,2005,2010,2015];

urlArray = [];

for(let i = 0; i < yearArray.length; i++) {
  year = yearArray[i];
  url = url.replace('year%3A' + (year-5), 'year%3A' + year);
  urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990);
for(let i = 0; i < yearArray.length; i++) {
  year = yearArray[i];
  url = url.replace('year%3A' + (year-5), 'year%3A' + year).replace('code%3A' + 1, 'code%3A' + 2);
  urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990);
for(let i = 0; i < yearArray.length; i++) {
  year = yearArray[i];
  url = url.replace('year%3A' + (year-5), 'year%3A' + year).replace('code%3A' + 2, 'code%3A' + 3);
  urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990);
for(let i = 0; i < yearArray.length; i++) {
  year = yearArray[i];
  url = url.replace('year%3A' + (year-5), 'year%3A' + year).replace('code%3A' + 3, 'code%3A' + 4);
  urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990);
for(let i = 0; i < yearArray.length; i++) {
  year = yearArray[i];
  url = url.replace('year%3A' + (year-5), 'year%3A' + year).replace('code%3A' + 4, 'code%3A' + 5);
  urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990);
for(let i = 0; i < yearArray.length; i++) {
  year = yearArray[i];
  url = url.replace('year%3A' + (year-5), 'year%3A' + year).replace('code%3A' + 5, 'code%3A' + 6);
  urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990);
for(let i = 0; i < yearArray.length; i++) {
  year = yearArray[i];
  url = url.replace('year%3A' + (year-5), 'year%3A' + year).replace('code%3A' + 6, 'code%3A' + 7);
  urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990).replace('code%3A' + 7, 'code%3A' + 1);;
console.log(urlArray);

let value = [];
for (i = 0; i<5; i++) {
  const url = urlArray[i];
  if (url) {
    fetch(url)
      .then((response) => response.text())
      .then((jsonResponse) => {
        const jsonObject = JSON.parse(jsonResponse);
        value.push(jsonObject.features[0].properties.year);
        
      });
  } 

}

console.log(value);

});

fetch 是一个异步 Promise,接收响应的顺序将决定服务器处理请求的速度,这可能取决于查询和数据的复杂性。要以固定顺序处理响应,请使用 Promise.all 参见 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

let value = [];
let fetches = [];
for (i = 0; i<5; i++) {
  const url = urlArray[i];
  if (url) {
    fetches.push(fetch(url));
  }
}
Promise.all(fetches).then((responses) => {
  responses.forEach((response) => {
    ...
  }); 
});

好的,所以我找到了解决方案here:

let value = [];
const fetchAll = async (urls) => {
  const res = await Promise.all(urls.map(u => fetch(u)))
  const jsons = await Promise.all(res.map(r => r.json()))

  for (i = 0; i< jsons.length; i++) {
    const val = jsons[i].features[0].properties.year;
    value.push(val);
  }
}
fetchAll(urlArray);