【问题标题】:Get password for a user returns undefined using node js express js使用节点 js express js 获取用户的密码返回未定义
【发布时间】:2021-03-30 17:37:53
【问题描述】:

我正在尝试实现一个用例,用户可以通过提供用户名来请求检查他的密码。 问题:Node js 后端应用在查询完成之前返回结果。我查看了解释 javascript 异步方面的文章。但是,我仍然不确定是否可以在中间涉及休息呼叫时应用这些解决方案。

高级流程:

  1. 前端js用用户名调用rest api(node.js应用)获取密码
  2. 节点应用调用数据库获取密码
  3. 返回密码显示在前端

代码:

前端:

function getPassword() {//Called by clicking button on ui
var username = 'testuser'; //hardcoding for simplicity
  $.ajax({
    url: urlWhereNodeJsAppIsHosted,
    error: function(password) {
      console.log('error' + JSON.stringify(password));
    }, success: function(data) {
      console.log('success' + JSON.stringify(password)); // Displaying on console for now
    }
  });
}

后端(Node js 应用):

const express = require('express');
const request = require('request');
const mysql = require('mysql');
const app = express();

var connection = mysql.createConnection({
    host: 'localhost',
    port: '3306',
    user: 'dbuser',
    password: 'dbuserpassword',
    database: 'dbname'
});

connection.connect(function(err) {
  if (err) {console.log(err);}
});

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  next();
});

app.get('/verify', (req, res) => {
  var username = req.query.username;
  var password = 'noresult';
  connection.query(
    'SELECT * FROM userpassword where user=?, ${[username]}', 
    function(err, rows, fields) {
      password = extractpasswordfromrows(rows);//iterate and get result
    }
  );
  console.log(connection.threadId); //Value is not undefined
  res.send(200, { success: password });
});

const PORT = process.env.PORT || 3001;
app.listen(PORT, () => console.log(`listening on ${PORT}`));

数据库:

userpassword(user, password) table with existing data.

我是 javascript 的新手,也是异步思考的。请帮助您的输入。谢谢。

【问题讨论】:

  • 看看promise...

标签: javascript mysql node.js ajax express


【解决方案1】:

代码在成功回调之外发送password,而不等待查询完成。试试

app.get('/verify', (req, res) => {
var username = req.query.username;
var password = 'noresult';
connection.query(
 'SELECT * FROM userpassword where user=?, ${[username]}', 
 function(err, rows, fields) {
   password = extractpasswordfromrows(rows);//iterate and get result
   res.send(200, { success: password }); // Ok, have password here
   }
 );
 // Not Ok, don't have password here
 console.log(connection.threadId); //Value is not undefined
});

我没有尝试输入检查代码来验证回调中的err 参数是否不真实,即使在逻辑上被认为是不可能的。

有关针对此错误进行编码的一般处理,请参阅"How do I return the result from an asynchronous call"

回调外的处理结果

为避免嵌套代码,回调代码可以根据处理结果解析或拒绝新创建的 Promise,并使用其 then/catch 方法将结果和错误处理函数附加到 Promise 上。

或者在 Express 中,您可以向app.get 提供多个回调(中间件函数),并在需要时使用next 调用前进到下一个中​​间件函数。作为基于帖子的示例(已编译但未测试):

app.get('/verify', 

  (req, res, next) => {
    var username = req.query.username;
    connection.query(
      'SELECT * FROM userpassword where user=?, ${[username]}', 
       function(err, rows, fields) {
         if( err) {
           res.status(500).send("no result");
         }
         else {
           res.locals.rows = rows;
           next();
         }
       }
     );
  },

  (req,res) => {
     const password = extractpasswordfromrows(res.locals.rows); //iterate and get result
     res.send(200, { success: password });
  }
);

【讨论】:

  • 感谢您的意见。如果我按照建议移动回调内部的 res.send,我就能得到结果。如果我保留在两个地方(在回调内部和问题的原始位置),我会得到密码的初始化值('noresult')。您能否帮助解释为什么从异步函数更新 res/result 时不会立即发回它。我认为一旦调用了任何异步函数(此处为 connect.query),代码执行将移至后续行,因为这里我们没有其他行,它将从 app.get(/verify, ...) 调用中退出,并带有空 res。
  • 如果有帮助,connection.query 不是异步函数:它在启动查询之后但在完成之前同步返回。只有在查询实际完成后才会调用回调。请参阅有关将 res.send 置于回调之外的更新帖子。
猜你喜欢
  • 2018-03-26
  • 1970-01-01
  • 2018-10-11
  • 1970-01-01
  • 2020-07-16
  • 1970-01-01
  • 2018-06-10
  • 1970-01-01
  • 2020-06-01
相关资源
最近更新 更多