简体   繁体   中英

How can I make sure that the function inside 'for loop' gets executed before I send the response in NodeJS?

I am using bluebird for this. I need to get this function ie get_like_status(email, results[i].id) which is at the end of the for loop to execute before I send the headers. I get it undefined when I console the array list. I would appreciate it enormously if you can do it using bluebird however I am open to any other packages for promises.

var list = new Array();
  console.log(results.length);
  function get_like_status(email, project_id){
    connection.query("SELECT email FROM likes WHERE liked_by='"+email+"' AND project_id='"+project_id+"';", function(err, results, fields){
      if(err){console.log(err); return(err)}else{
        if(results.length > 0){
          console.log("yes");
          return "yes";
        }else{
          console.log("yes");
          return "no";
        }
      }

    })
  }
  for(var i=0; i < results.length; i++){
    var empty = new Array();
    list.push(empty);
    list[i].push(results[i].email);
    list[i].push(results[i].project_name);
    list[i].push(results[i].project_description);
    list[i].push(results[i].header_image);
    list[i].push(results[i].id);
    list[i].push(get_like_status(email, results[i].id)); // This gets executed after the program has sent response!
  }
  Promise.all(list).then(function(){
    console.log(list);
    res.send(list); });

You have to refactor your code to actually wait for the promises, right now the list array is just a regular array with different values, it's not an array of promises waiting to be resolved.

Something similar to this

function get_like_status(email, project_id) {
    return new Promise(function( res, rej ) {
        var query = "SELECT email FROM likes WHERE liked_by='" + 
                    email + "' AND project_id='" + project_id + "';"

        connection.query(query, function(err, results, fields) {
            if (err) {
                rej(err);
            } else {
                res( results.length > 0 ? "yes" : "no" );
            }
        });
    });
}

var promises = [];
var list = results.map(function(item, index) {
    var arr = [
        item.email,
        item.project_name,
        item.project_description,
        item.header_image,
        item.id
    ]
    promises.push( 
        get_like_status(item.email, item.id).then(function(res) { 
            arr.push(res);
            return arr;
        }) 
    );
})

Promise.all( promises ).then(function() {
    res.send(list);
}).catch(function( err ) {
    res.send('epic fail!')
})

Note that if connection.query returns a promise, there's no need to wrap it in another promise, it's just not clear where connection.query is coming from?

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