简体   繁体   中英

function call with ASYNC/AWAIT

I'm sure this issue is from my lack of async/await knowledge. However, I cannot figure out what I am doing wrong. Endgoal is for the addSupplier() process to wait on getSuppliers() function to finish processing until it continues.

Background info: This is inside of a much larger Electron application utilizing HTML, JS, and Postgres. This snippet of code is processing a request from HTML form to insert a supplier into the table, then refresh the HTML table which is located on the same page. HTML code is not shown but I can include if needed.

Current code - not split into separate functions - works as desired:

function addSupplier(){
  const connString = getConnData();
  const client = new Pool(connString)
  client.connectionTimeoutMillis = 4000;

  var supplierID = document.getElementById("dbSupplierID").value;
  var supplierName = document.getElementById("dbSupplierName").value;
  var supplierUnit = document.getElementById("dbSupplierUnit").value;

  const supplier_insert_query = {
    text: "INSERT INTO suppliers(supplier_id, company, unit)VALUES('"+ supplierID +"', '"+ supplierName +"', '"+ supplierUnit +"')",
  }

  const supplier_select_query = {
    text: "SELECT supplier_id AS id, company, unit FROM suppliers",
    rowMode: 'array',
  }

  // Connect to client, catch any error. 
  client.connect()
  .then(() => console.log("Connected Successfuly"))
  .catch(e => console.log("Error Connecting"))
  .then(() => client.query(supplier_insert_query))
  .catch((error) => alert(error))
  .then( () => { // After inserting new author, run author query and refresh table. 
    client.query(supplier_select_query)
    .then(results => {
      // Create the static header for the table
      var table = ""; table_head = ""
      for (i=0; i<results.fields.length; i++) { if (i==3) {continue}
        table_head += '<th>' + results.fields[i].name + '</th>'
      }

      // Create the body of the table
      for (j=0; j<results.rows.length; j++) { //j: rows, k: columns
        results.rows[-1] = []
        if (results.rows[j][0] == results.rows[j-1][0]) {continue}
        table += '<tr>'
        for (k=0; k<results.fields.length; k++) { if (k==3) {continue} // Skip creating the last column of this query. This data is only used to add information to the first column.
          if (k==0) { // When you've reached a session_id cell, write the names of the tests in this session in that cell
            var x=0; x = j; var tests = ''
            while (results.rows.length > x && results.rows[x][0] == results.rows[j][0]) {
             tests += '<br>' + (results.rows[x][3]==null ? '':results.rows[x][3]); x++
            }
          }
          table += `<td>${results.rows[j][k]}` + (k==0 ? `${tests}`:``) + '</td>'
        }
        table += '</tr>'
      }

      // Grab the constructed HTML strings and write them to the document to create the table there
      document.getElementById('supplier_table_head').innerHTML = ""
      document.getElementById('supplier_table').innerHTML = ""

      document.getElementById('supplier_table_head').innerHTML += table_head
      document.getElementById('supplier_table').innerHTML += table
    }).catch(e => console.error("ERROR in supplier table query\n",e.stack))
  })
    
  // Clearing input fields.
  document.getElementById('dbSupplierID').value = ""
  document.getElementById('dbSupplierName').value = ""
  document.getElementById('dbSupplierUnit').value = ""

  // Preventing app refresh
  event.preventDefault()
  
  .finally(() => client.end())
}

EDIT: I made the async changes and it seems to call the function correctly but the function does not process. This is what I have now. If I throw in an alert, it processes the alert 'TypeError: Promise resolver undefined is not a function' and then kicks out and refreshes the entire application.

// Function to add a supplier to the DB
async function addSupplier(){
  const connString = getConnData();
  const client = new Pool(connString)
  client.connectionTimeoutMillis = 4000;

  var supplierID = document.getElementById("dbSupplierID").value;
  var supplierName = document.getElementById("dbSupplierName").value;
  var supplierUnit = document.getElementById("dbSupplierUnit").value;

  const supplier_insert_query = {
    text: "INSERT INTO suppliers(supplier_id, company, unit)VALUES('"+ supplierID +"', '"+ supplierName +"', '"+ supplierUnit +"')",
  }

  // Connect to client, catch any error. 
  client.connect()
  .then(() => console.log("Connected Successfuly")) // Connection is good
  .catch(e => console.log("Error Connecting"))      // CATCH - Connect error
  .then(() => client.query(supplier_insert_query))  // Run supplier insertion query
  .catch((error) => alert(error))                   // CATCH - error in insertion query
  .then(async () => {
    // wait for getSuppliers function to execute
    await getSuppliers();
  }) 
  .then(() => {
    // Clearing input fields.
    document.getElementById('dbSupplierID').value = ""
    document.getElementById('dbSupplierName').value = ""
    document.getElementById('dbSupplierUnit').value = ""

    // Preventing app refresh
    event.preventDefault()
  })
  .catch(e => console.error("ERROR in supplier table query\n",e.stack)) //Catch any error from getSuppliers
  .finally(() => client.end())                      // Close the connection
}

async function getSuppliers(){
  let promise = new Promise()
  // Query to pull all Suppliers info from database
  const supplier_select_query = {
    text: "SELECT supplier_id AS id, company, unit FROM suppliers",
    rowMode: 'array',
  }

  // Query the database and pull the results into the HTML table
  client.query(supplier_select_query)
    .then(results => {
      // Create the static header for the table
      var table = ""; table_head = ""
      for (i=0; i<results.fields.length; i++) { if (i==3) {continue}
        table_head += '<th>' + results.fields[i].name + '</th>'
      }

      // Create the body of the table
      for (j=0; j<results.rows.length; j++) { //j: rows, k: columns
        results.rows[-1] = []
        if (results.rows[j][0] == results.rows[j-1][0]) {continue}
        table += '<tr>'
        for (k=0; k<results.fields.length; k++) { if (k==3) {continue} // Skip creating the last column of this query. This data is only used to add information to the first column.
          if (k==0) { // When you've reached a session_id cell, write the names of the tests in this session in that cell
            var x=0; x = j; var tests = ''
            while (results.rows.length > x && results.rows[x][0] == results.rows[j][0]) {
             tests += '<br>' + (results.rows[x][3]==null ? '':results.rows[x][3]); x++
            }
          }
          table += `<td>${results.rows[j][k]}` + (k==0 ? `${tests}`:``) + '</td>'
        }
        table += '</tr>'
      }

      // Grab the constructed HTML strings and write them to the document to create the table there
      document.getElementById('supplier_table_head').innerHTML = ""
      document.getElementById('supplier_table').innerHTML = ""

      document.getElementById('supplier_table_head').innerHTML += table_head
      document.getElementById('supplier_table').innerHTML += table
    })
  .finally(() => {return promise.resolve()})
}

You need to prefix function declaration with async key word to use await key word inside of it.


client.connect()
  .then(() => console.log("Connected Successfuly")) // Connection is good
  .catch(e => console.log("Error Connecting"))      // CATCH - Connect error
  .then(() => client.query(supplier_insert_query))  // Run supplier insertion query
  .catch((error) => alert(error))                   // CATCH - error in insertion query
  .then(async () => {
    // wait for getSuppliers function to execute
    await getSuppliers()

    // Clearing input fields.
    document.getElementById('dbSupplierID').value = ""
    document.getElementById('dbSupplierName').value = ""
    document.getElementById('dbSupplierUnit').value = ""

    // Preventing app refresh
    event.preventDefault()
  }) 

The await keyword waits for a promise to be resolved before running code after it ( await in Javascript ). You haven't made getSuppliers create or resolve a promise, so await isn't waiting for anything here. I'm not very familiar with creating and resolving promises myself, but something like promise = new Promise() at the beginning of getSuppliers and return promise.resolve() at the end should work properly.

EDIT: It also seems like you're missing an async before the arrow function with await getSuppliers() , that could be causing issues as well. I might have jumped the gun on assuming promises were the issue, as the await keyword does try to convert anything that isn't a promise to a resolved one, but I'm not familiar with how consistently this works the way it should.

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