使用 Q 使用 Node.js 服务器链接数据库查询

Using Q to chain Database queries using Node.js server

首先,我仍在学习 promises,因此我真的可以在这方面得到一些帮助。我有:

            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);
                            }
                        });

所以在这个块中,我查询我的数据库,根据他们的 spotify ID 查找用户是否存在(用户必须先登录才能在我的应用程序上进行 spotify,所以我用它来检查他们是否已经存在也在我的数据库中)如果它在我的数据库中找到 spotify ID,那么它会获取行中的信息,然后 defer.resolve 转到 defer.promise.then,数据返回到客户端。

我遇到的问题是在 else 语句中,如果用户不存在,它会为他们插入一行。此插入现在可以正常工作,但我还需要在创建行后进行另一个查询以从中获取信息,以便客户端可以使用数据库 ID。我正在努力让获取 ID 查询在插入后执行。目前,在此代码中,我正在尝试回调以在之后执行,但它不起作用。我也尝试过使用 .then 但我现在有点卡住了。感谢您的帮助!

你确实可以使用 promises,像这样:

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();