NodeJS在功能完成之前响应

时间:2017-05-02 14:54:25

标签: javascript node.js rest express mongoose

我正在为一个学校项目编写一个带有NodeJS和Express的API,我正在努力解决以下问题:

函数getAuthUserId解码JWT令牌并从mongoDB服务器中的用户获取Id。

我在REST调用“/ user / authTest”中调用此函数。但是当我调用它时,服务器会在数据库返回Id之前响应,并且变量UId未定义。如您所见,ID实际上已找到。关于如何解决这个问题的任何想法?

API调用代码:

apiRoutes.post('/user/authTestID', function(req, res) {
  var UId = getAuthUserId(req, res);
  console.log(UId);
  if (UId) {
    res.sendStatus(200);
  }else{
    res.sendStatus(400);
  }

}); 

功能:

function getAuthUserId(req, res) {
    var user = new User();
  var token = user.getToken(req.headers);
  if (token) {
    var decoded = jwt.decode(token, config.secret);
    User.findOne({
      name: decoded.name
    }, function(err, user) {
        if (err) throw err;

        if (!user) {
          res.status(403).send({success: false, msg: 'Authentication failed. User not found.'});
          return false
        } else {
          console.log('Auth for ' + user.name + ' ' + user._id);
          return user._id
        }
    });
  } else {
    res.status(403).send({success: false, msg: 'No token provided.'});
    return '';
  }
}

终端的输出:

[nodemon] restarting due to changes...
[nodemon] starting `node server.js`
Connected to MongoDB
undefined
::ffff:192.168.0.111 - POST /user/authTestID HTTP/1.1 400 11 - 175.006 ms
Auth for test 58f8954c3602b80552b6f1fb

提前致谢!

3 个答案:

答案 0 :(得分:2)

你需要做出承诺,就像这样。

API

apiRoutes.post('/user/authTestID', function(req, res) {
  getAuthUserId(req, res).then(function (UId) => {
    console.log(UId);

    if (UId) {
      res.sendStatus(200);
    }else{
      res.sendStatus(400);
    }
  });

}, function(err) {
    console.log(err.msg)
    res.status(err.status).send(err.msg);
});

功能

function getAuthUserId(req, res) {
    return new Promise(function(resolve, reject){
        var user = new User();
        var token = user.getToken(req.headers);
        if (token) {
            var decoded = jwt.decode(token, config.secret);
            User.findOne({
                name: decoded.name
            }, function(err, user) {
                if (err) throw err;

                if (!user) {
                    reject({status: 403, msg: 'Authentication failed. User not found.'});
                } else {
                    console.log('Auth for ' + user.name + ' ' + user._id);
                    resolve(user._id)
                }
            });
        } else {
            reject({status: 403, msg: 'No token provided.'});
        }
    })
}

答案 1 :(得分:2)

getAuthUserId获取 CALLBACK !!! 中的值。你不能指望它从它返回值。快速的事情你可以做如下的事情。

        apiRoutes.post('/user/authTestID', function (req, res) {
            var user = new User();
            var token = user.getToken(req.headers);
            if (token) {
                var decoded = jwt.decode(token, config.secret);
                User.findOne({
                    name: decoded.name
                }, function (err, user) {
                    if (err) throw err;
                    if (!user) {
                        return res.status(403).send({success: false, msg: 'Authentication failed. User not found.'});
                    } else {
                        console.log('Auth for ' + user.name + ' ' + user._id);
                        return res.send(user._id)
                    }
                });
            } else {
                return res.status(403).send({success: false, msg: 'No token provided.'});
                // return '';
            }
        });

尝试使用承诺库Bluebird

答案 2 :(得分:1)

詹姆斯的评论看起来像异步电话上的一个好的,彻底的资源。正如其他人所提到的,您无法在回调中返回值。您可以使用Promise库,也可以更改getAuthUserId函数以进行回调并在其中包含console.log逻辑:

示例:

API调用代码:

apiRoutes.post('/user/authTestID', function(req, res) {
  getAuthUserId(req, res, function(UId) {
  // we're in a your new callback
  console.log(UId);
  if (UId) {
    res.sendStatus(200);
  }else{
    res.sendStatus(400);
  }
  });
});

功能代码

// note new callback param
function getAuthUserId(req, res, callback) {
  var user = new User();
  var token = user.getToken(req.headers);
  if (token) {
    var decoded = jwt.decode(token, config.secret);
    User.findOne({
      name: decoded.name
    }, function(err, user) {
        if (err) throw err;

        if (!user) {
          res.status(403).send({success: false, msg: 'Authentication failed. User not found.'});
          callback(false) // no more return, call callback with value
        } else {
          console.log('Auth for ' + user.name + ' ' + user._id);
          callback(user._id) // no more return, call callback with value
        }
    });
  } else {
    res.status(403).send({success: false, msg: 'No token provided.'});
    callback(''); // no more return, call callback with value
  }
}