How to wait for a function or database query to complete? And then process the results and finally send them back

I have a scenario like this:

app.get('/', async function (request, response) 
{
     await foo(DbConnection).then((result) => console.log("response ready"));
})

let foo = async function (DbConnection)
{
    const myQuery = "SELECT * FROM my_table";

    DbConnection.query(myQuery, async function(err, results) {
       console.log("query ready");
       await bar(results).then((response) => console.log("bar done"))
    })
    return; // go back to app.get() to send stuff to client
}

let bar = async function (results)
{   
    console.log("inside bar");
    await ThirdPartyAPI(result).then((value)) => return value);
}

Short:

  • I get a GET request from a client

  • I call foo (), which queries the database and applies functions to the results

  • I process the results using a third-party API, which takes time to complete

  • I send the final results back to the client

I expect to see:

ready request → internal bar → done bar → response ready

But instead, I see:

the answer is ready → ready request → inner panel → done panel

The client receives undefinedbecause there was nothing whenresponse.send()

What could be the problem?

+4
1

, async/await. async , - .

, , connection.query() - . :

app.get('/', async (request, response) => {
    // waiting for the result of foo
    let result = await foo();
    console.log("response ready");
});

let foo = async () => {
    const myQuery = "SELECT * FROM my_table";

    // getting the result of the query
    let results = await new Promise((resolve, reject) => connection.query(myQuery, (err, results) => {
      if (err) {
        reject(err)
      } else {
        resolve(results);
      }
    }));
    console.log("query ready");
    // call bar and waiting the result
    let res = await bar(results);
    console.log("bar done");
    // return resolved promise
    return res;
}

let bar = (results) => {   
    console.log("inside bar");
    // just return a promise, we don't need the result here
    return ThirdPartyAPI(result);
}

async/await. async/await , . , async. async , , ( , , , ). , , , .

async/await, :

  • , ( ).
  • async , .
  • async , , ( , ).

:

1.sync, userId. validateParams true/false, validateParams2 , userId - undefined. validateParams3 : validateParams3().then(...).

let validateParams = (userId) => {
  return userId;
}

let validateParams2 = (userId) => {
  if (!userId) {
    throw new Error('userId is undefined');
  }
}

let validateParams3 = (userId) => {
  if (!userId) {
    return Promise.reject(new Error('userId is undefined'));
  }
  return Promise.resolve();
}

2.async . getUser ( userId ) ( userId - undefined). , getUser : createUser().then(...). getUser2 getUser3 , . , unhandledError, validateParams2 . getUser2 makred as async ( ), getUser3 .

let getUser = (userId) => {
  if (validateParams(userId)) {
    return db.getUserById(userId);
  }
  return Promise.resolve();
}

let getUser2 = async (userId) => {
  validateParams2(userId);
  return db.getUserById(userId);
}

let getUser3 = (userId) => {
  return Promise
    .resolve(userId)
    .then(validateParams2)
    .then(() => db.getUserById(userId);
}

3.async :

let updateUser = async (userId, userData) => {
  let user = await getUser(userId);
  _.extend(user, userData);

  return db.saveUser(user);
}

:

// with async
let fn = async (userId, userData) => { 
  try {
    let user = await updateUser(userId, userData);
    console.log(user);
  }
  catch (err) {
    console.log(err);
  }
}

// without async
let fn2 = (userId, userData) => { 
  updateUser(userId, userData)
    .then(user => console.log(user))
    .catch(err => console.log(err))
  }
}
+5

Source: https://habr.com/ru/post/1683994/


All Articles