简体   繁体   中英

Using Q to chain Database queries using Node.js server

To start I'm still learning about promises so I could really use some help on this. I've got:

            request.get(options, function(error, response, body) {
                connection.query('SELECT * FROM `users` WHERE `spotify_id` = ' + body.id, function(error, results, fields) {
                    var getIdQuery = 'SELECT `id` FROM `users` WHERE `spotify_id` = ' + body.id;
                    if (results.length != 0) {
                        console.log("this user already exists");
                        connection.query(getIdQuery, function(error, results, fields) {
                            tokenAndId['id'] = results[0]['id'];
                            defer.resolve(tokenAndId);
                        });
                    } else {
                        var setUserQuery = 'INSERT INTO `users` (`spotify_id`) VALUES (' + body.id + ');';
                        connection.query(setUserQuery, function(){
                            connection.query(getIdQuery, function(error, results, fields) {
                                defer.resolve(tokenAndId);
                            }
                        });

So in this block I have query to my database that finds whether a user exists based off their spotify ID(the user has to log in to spotify first on my app so I use that to check whether they also already exist in my database as well) if it finds the spotify ID in my database then it grabs the information in the row and then defer.resolve goes to a defer.promise.then where the data is returned to the client-side.

The problem I'm having is in the else statement where, if a user doesn't exist than it inserts a row for them. This insert works correctly right now but I need to also make another to query to grab the information from it after I've created the row, so that the client side can make use of the database id. I'm struggling trying to get the the get ID query to execute after the Insert. Currently, in this code I'm attempting a callback to execute afterwards but it isn't working. I've tried using .then as well but I'm kinda stuck right now. Thanks for any help!

You can indeed use promises, like so:

var Q = require('q');

function getId() {
  console.log('Getting id...');
  var deferred = Q.defer();
  request.get(options, function(error, response, body) {
    if (error) return deferred.reject(error);
    deferred.resolve(body.id);
  });
  return deferred.promise;
}

function getUserExists(id) {
  console.log('Getting user exists for', id, '...');
  var deferred = Q.defer();
  connection.query('SELECT * FROM `users` WHERE `spotify_id` = ' + id, function(error, results, fields) {
    if (error) return deferred.reject(error);
    deferred.resolve(results.length != 0);
  });
  return deferred.promise;
}

function getUserId(id) {
  console.log('Getting user id for', id, '...');
  var deferred = Q.defer();
  connection.query('SELECT `id` FROM `users` WHERE `spotify_id` = ' + id, function(error, results, fields) {
    if (error) return deferred.reject(error);
    if (results.length === 0) return deferred.reject(new Error('User not found'));
    deferred.resolve(results[0]['id']);
  });
  return deferred.promise;
}

function insertUser(id) {
  console.log('Inserting user for', id, '...');
  var deferred = Q.defer();
  connection.query('INSERT INTO `users` (`spotify_id`) VALUES (' + id + ');', function(error) {
    if (error) return deferred.reject(error);
    deferred.resolve(id);
  });
  return deferred.promise;
}

getId()
    .then(function(id) {
      return getUserExists(id)
          .then(function(userExists) {
            if (userExists) {
              return Q.when(id);
            } else {
              return insertUser(id);
            }
          })
    })
    .then(function(id) {
      return getUserId(id);
    })
    .then(function(userId) {
      console.log('Found user id', userId);
      tokenAndId['id'] = userId;
      return Q.when(tokenAndId);
    })
    .then(function(tokenAndId){
      //do something with tokenAndId
      console.log(tokenAndId);
    })
    .fail(function(error){
      //Oups! Error! Handle it here...
      console.error(error);
    })
    .done();

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