简体   繁体   中英

How to wait for elements to be created with async-await?

hope you all are having a good day.

I try to make fillClassData() wait for createClassElementsWith() . I figured I have to use async await and return a promise, data somehow to make it work. Any ideas how to solve this in a clean readable way? What would I return?

Code:

// 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);
}

data example:

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

Btw. the function fillClassData() is called based on a select option of a prop . The function fillTableData() fills in a table with the data gotten based on those two selects.

My favorite workaround for something like this is to add a setTimeout() . The delay can be 1 ms or 5ms, whichever seems more dependable to you. Put all of the code that depends on createClassElementsWith in the timeout.

// 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);
}

I figured it out. Big thanks to the people commenting and trying to help but the problem was somewhere completely else. I guess my debugging skills are not the greatest and I started looking at the wrong end.

I saved selected options in the local storage but I didn't clear the saved class whenever a new prop was selected. Which means the data can't be fetched correctly, the parameters don't match up. I added a function to my config now: config.clearClass(); which clears the class item in the localstorage.

The word async has one simple meaning: this function always returns a promise. Other types of values are automatically wrapped in a successful promise.

async function f() { return 1; }

You can explicitly return a promise, the result will be the same:

async function f() {

return Promise.resolve(1); }

f().then(alert); // 1

The await keyword will cause the JavaScript interpreter to wait until the promise to the right of await is executed. After which it will return its result, and the code execution will continue. // Works only inside async functions

let value = await promise;

enter code here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM