select 列表选项的异步加载

Asynchronous loading of select list options

我正在使用 AJAX 从 public 服务提供商 (DAWA) 检索有关市政名称、邮政编码等的信息。起初我在检索数据时遇到问题,直到我将传输设为异步,因此 ajaxGetMunicipalitiesFromDAWA 是一个异步函数。我检查了 ajaxGetMunicipalitiesFromDAWA 并且它正确加载了数据。

我尝试使用数据更新我的选择列表,但更新似乎发生在市政当局加载之前。我也尝试使 loadMunicipalities 异步,但最终我仍然得到一个空的选项列表。

请帮忙

HTML代码:

<div class="row mt-3 fw-bold">
    <div class="col-3"><label asp-for="PostalAddress_Municipality">Municipality:</label></div>
    <div class="col-9">
        <select asp-for="PostalAddress_MunicipalityId" class="form-control form-control-sm" name="municipality"></select>
    </div>
</div>

JavaScript:

    var Municipalities = ajaxGetMunicipalitiesFromDAWA();
    
async function ajaxGetMunicipalitiesFromDAWA() {
    var output = [];
    var xHttp = new XMLHttpRequest();
    xHttp.onreadystatechange = function () {
        if (this.readyState == 4 && this.status == 200) {
            var dawaData = JSON.parse(this.responseText);
            dawaData.forEach(function (data) {
                output.push({ Id: data.kode, Name: data.navn, CountryId: 53, CountryText: "Danmark", RegionId: data.regionskode, RegionText: data.region.navn });
            });
        }
    }
    xHttp.open("GET", "https://dawa.aws.dk/kommuner", true);
    await xHttp.send();
    return output;
}

async function loadMunicipalities() {
    var select = document.querySelector("municipality");
    var data = await Municipalities;
    data.forEach(function (municipality) {
        var option = document.createElement("option");
        option.value = municipality.Id;
        option.text = municipality.Name;
        option.selected = select.value == municipality.Id;
        select.add(option);
    });
}

两件事,XMLHttpResquest.send 没有 return 承诺。所以等待 send 只会等待一个空的微任务完成,而不是实际的请求。你想要做的只是将请求包装在一个 Promise 中,它将由异步 FSM 处理。您还需要实际调用 loadMunicipalities 以便实际填充列表。下面是一个工作示例。

var Municipalities = ajaxGetMunicipalitiesFromDAWA();

async function ajaxGetMunicipalitiesFromDAWA() {
  var output = [];
  var xHttp = new XMLHttpRequest();
  return new Promise((resolve) => {
    xHttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        var dawaData = JSON.parse(this.responseText);

        dawaData.forEach(function(data) {
          output.push({
            Id: data.kode,
            Name: data.navn,
            CountryId: 53,
            CountryText: "Danmark",
            RegionId: data.regionskode,
            RegionText: data.region.navn
          });
        });

        resolve(output);
      }
    }
    xHttp.open("GET", "https://dawa.aws.dk/kommuner", true);
    xHttp.send();
  });

}

async function loadMunicipalities() {
  var select = document.querySelector("#municipality");
  var data = await Municipalities;

  data.forEach(function(municipality) {
    var option = document.createElement("option");
    option.value = municipality.Id;
    option.text = municipality.Name;
    option.selected = select.value == municipality.Id;
    select.add(option);
  });
}

loadMunicipalities();
<select id="municipality"></select>

所以这按原样工作,但由于您使用的是半现代 api,id 建议您使用 fetch,因为它处理几乎所有应用的修复,但使代码不那么冗长。

const requestMunicipalitiesFromDAWA = async() => {
  const response = await fetch("https://dawa.aws.dk/kommuner");
  const data = await response.json();
  
  return data.map((datum) => ({
    Id: datum.kode,
    Name: datum.navn,
    CountryId: 53,
    CountryText: "Danmark",
    RegionId: datum.regionskode,
    RegionText: datum.region.navn
  }));
};

const populateMunicipalitiesOptions = (data) => {
  var select = document.querySelector("#municipality");
 
  data.forEach(function(municipality) {
    var option = document.createElement("option");
    option.value = municipality.Id;
    option.text = municipality.Name;
    option.selected = select.value == municipality.Id;
    select.add(option);
  });
};

requestMunicipalitiesFromDAWA().then(populateMunicipalitiesOptions);
<select id="municipality"></select>