首页 > 解决方案 > 如何等待使用 async-await 创建元素?

问题描述

希望你们今天过得愉快。

我试着让fillClassData()等待createClassElementsWith()。我想我必须使用异步等待并返回一个承诺,数据以某种方式使其工作。任何想法如何以一种清晰易读的方式解决这个问题?我会返回什么?

代码:

// get data
async function fillClassData() {
  const prop_id = prop_select.children('option:selected').val();
  const selected_class = config.getClass();
  // fetch data
  const data = await api.fetchClass(prop_id);

  // create options
  await createClassElementsWith(data);

  if (itemsExist(selected_class)) {
    class_select.val(selected_class);
    // fill table info
    fillTableData();
  }
}

// creates options for classes
async function createClassElementsWith(data) {
  // clear options
  class_select.find('option').remove();
  // create new options per entry
  if (data.length <= 0) {
    generateOption('default', 'No options yet', class_select);
  } else {
    generateOption('default', 'Select Class...', class_select);
    for (let item of data) {
      generateOption(item.class_id, item.class_name, class_select);
    }
  }
  class_select.children('option')[0].selected = true;
}

// creates element with given parameters
function generateOption(value, text, select) {
  // create element
  let opt = document.createElement('option');
  opt.value = value;
  opt.innerHTML = text;
  // set some options to disabled
  if(value === 'default') opt.setAttribute('disabled', true);
  // append to select
  select.append(opt);
}

数据示例:

class_id: "3179807"
class_longname: "long class name"
class_name: "short class name"

顺便提一句。该函数fillClassData()是根据 a 的选择选项调用的prop。该函数fillTableData()使用基于这两个选择获得的数据填充一个表。

标签: javascriptjqueryasync-await

解决方案


我最喜欢的解决方法是添加一个setTimeout(). 延迟可以是 1 毫秒或 5 毫秒,以您认为更可靠的为准。将所有依赖的代码放在createClassElementsWith超时中。

// get data
async function fillClassData() {
  const prop_id = prop_select.children('option:selected').val();
  const selected_class = config.getClass();
  // fetch data
  const data = await api.fetchClass(prop_id);

  // create options
  createClassElementsWith(data); // Nothing to wait for like evolutionxbox said

  setTimeout(() => {
    if (itemsExist(selected_class)) {
      class_select.val(selected_class);
      // fill table info
      fillTableData();
    }
  }, 1); // 1 ms should be enough time for createClassElements to run
}

// creates options for classes
function createClassElementsWith(data) {
  // clear options
  class_select.find('option').remove();
  // create new options per entry
  if (data.length <= 0) {
    generateOption('default', 'No options yet', class_select);
  } else {
    generateOption('default', 'Select Class...', class_select);
    for (let item of data) {
      generateOption(item.class_id, item.class_name, class_select);
    }
  }
  class_select.children('option')[0].selected = true;
}

// creates element with given parameters
function generateOption(value, text, select) {
  // create element
  let opt = document.createElement('option');
  opt.value = value;
  opt.innerHTML = text;
  // set some options to disabled
  if(value === 'default') opt.setAttribute('disabled', true);
  // append to select
  select.append(opt);
}

推荐阅读