0

In my nodejs project, there's a function where I have two queries to get data from. First query is dependent on a flag, if flag is true, then I've to run that query and pass its data to second query. Otherwise I've to set some hard-coded data for second query. But it does not wait for first query response and run second query. I've added callbacks to it but nothing worked for me. Here is my code snippet;

getData(req, callback) {

if(!req.flag){ 
        lstData.push('d');// hardcoded data
        
        return Reader.open(filename).then(reader => {
            
            let code = reader.data;
            
            if(!!code ){
                return dao.getFirstData(code , (err, results) => {
                    if (err) return callback(err);
                    
                    if(results && results.length > 0){
                        return lstData = results;
                                        
                    }
                    
                });
            }
          
        });
    }
    else{ 
        lstData.push('d');// hardcoded data
    }
    
    let asyncFuncs = [
        (callback) => {
            dao.getSecondData(lstData, (err, results) => {
                if (err) return callback(err);
                return callback(null, { amounts: results });
            });
        }
    ];

 asyncFuncs.push(callback => {
            dao.thirdFunction(id, callback);
        });

 async.parallel(asyncFuncs, (err, results) => {
        
        if (err) return callback(err);
        let data1= results[0].amount;
        let data2= results[1];
        // some calculations with data1 & data2
        return callback(err, finalResult);
    });
}

No matter flag is true or false, getSecondData always returns data against d (hard-coded value). I am a newbie to nodejs, so please let me know what am I doing wrong.

SO I updated my code to add promise in it...here is updated code;

getData(req, callback) {

if(!req.flag){ 
        lstData.push('d');// hardcoded data
        
        Reader.open(filename).then(reader => {
            
            let code = reader.data;
            
            if(!!code ){
              var prom = new Promise((resolve, reject) => {
                dao.getFirstData(code , (err, results) => {
                    if (err) return callback(err);
                    
                    if(results && results.length > 0){
                        let lstData = results;
                        return resolve(lstData);
                                        
                    }
                    
                 });
                });
                
                prom.then((result) => {
                    return result;
                });
            }
          
        });
    }
    else{ 
        lstData.push('d');// hardcoded data
    }
    
    let asyncFuncs = [
        (callback) => {
            dao.getSecondData(lstData, (err, results) => {
                if (err) return callback(err);
                return callback(null, { amounts: results });
            });
        }
    ];

 asyncFuncs.push(callback => {
            dao.thirdFunction(id, callback);
        });

 async.parallel(asyncFuncs, (err, results) => {
        
        if (err) return callback(err);
        let data1= results[0].amount;
        let data2= results[1];
        // some calculations with data1 & data2
        return callback(err, finalResult);
    });
}

But still same response. It is not waiting for promise result.

Naila Akbar
  • 3,033
  • 4
  • 34
  • 76

2 Answers2

0

There plenty of ways to achieve this but I would prefer http://async.io/ to perform multi function operations.

By using promise you can do,

function f1(argument){
  return new Promise((resolve, reject) => {
     try {
         data = // do your thing
         resolve(data)
       }
     catch(err){
        reject(err)
      }
  })
}

and then use await to achieve this

async function caller(){
    await f1()
}

Few other links to help you [here][2]

[2]: https://stackoverflow.com/questions/22442321/callback-function-example/48333938#:~:text=A%20callback%20function%2C%20is%20a,or%20executed)%20inside%20the%20otherFunction.&text=Without%20thinking%20too%20much%2C%20see%20the%20following%20example.&text=Generally%2C%20JavaScript%20allows%20function%20as%20a%20parameter.

Piyush Dubey
  • 276
  • 1
  • 13
0

You can use async/await for asynchronous calls or you can uses promises. This will wait at the asynchronous calls and once you get the response your code will execute the dependent subsequent calls.

getData(req, callback) {

if(!req.flag){ 
        lstData.push('d');// hardcoded data --> this might be an issue as you are already pushing data.
        
//      these are async calls where you can ask your code to wait 
 return Reader.open(filename).then(reader => {
            
            let code = reader.data;
            
            if(!!code ){
        
               var promise = dao.getFirstData(code , (err, results) => {
                    if (err) reject(err);
                    
                    if(results && results.length > 0){
                         lstData = results;  
                         resolve(lstData);                   
                    }
                });
              return promise --> you can subscribe this using then
            }
          
        });
    }
    else{ 
        lstData.push('d');// hardcoded data
    }
    
    let asyncFuncs = [
         (callback) => {
            dao.getSecondData(lstData, (err, results) => {
                if (err) return callback(err);
                return callback(null, { amounts: results });
            });
        }
    ];
}



To get hands on this you can check the ways of using async/await

https://javascript.info/async-await

Apoorva Chikara
  • 8,277
  • 3
  • 20
  • 35
  • I can't use await, because in that case I have to update remaining functions as well. – Naila Akbar Jan 12 '21 at 12:21
  • you can use promise. and you can use SYNC way of reading file if it exist you can make a second call after reading the file else push the hardcode value. – Apoorva Chikara Jan 12 '21 at 12:35
  • issue is not with file reading, and this reader does not have `openSync` . Issue is with getFirstData function, this code does not wait for its result. – Naila Akbar Jan 12 '21 at 12:39
  • I think in if and else you are pushing your hardcode data. Yes, that is what you need to make a change you have to return a promise instead and subscribe to it. So, that once your async call gets the data you move on the next step. Right now your method is executing as it has to, but you need to make it return a callback once your async task is done and in this case it will always be pushing hardcode data be it in if block or not. – Apoorva Chikara Jan 12 '21 at 12:44
  • Yes you don't need to use it. You should be using the same function as it is. Only thing you need to change is how the function returns. Instead of returning the values directly you should return a promise and based on that call the second query. I have made the changes on code now for Reader.open. – Apoorva Chikara Jan 12 '21 at 13:09
  • please check updated question...still facing same issue – Naila Akbar Jan 12 '21 at 13:37
  • wrap your Reader.open into a promise function and call it in the getData and call it using await also remove the hardcoded item from the if condition. It will resolve your issue - as written by @Piyush Dubey - If above code doesn't work. You might need to change the way where you are calling getData – Apoorva Chikara Jan 12 '21 at 13:51