Переменные за пределами connection.query () не обновляются - PullRequest
0 голосов
/ 11 апреля 2019

У меня есть код входа в систему, который отправляет данные (введенные пользователем) в базу данных mysql, сопоставляет пароль и возвращает статус, основанный на успехе или неудаче проверки. Для этого у меня есть определенная функция. Переменная состояния объявляется внутри функции и обновляется через несколько операторов if, которые проверяют пароль. Однако, когда функция вызывается, она всегда возвращает значение по умолчанию статуса

Это код:

var con = mysql.createConnection({
 host: "localhost",
 user: "XXXXXX",
 password: "XXXXXX",
 database: "XXXXXX"
});
con.connect(function(err){
    if(err) throw err;
});

function confirm(uname,pass){
    var query = "select * from clients where name='"+uname+"' ";
    var stat = 0;
        con.query(query,function(err,result){
            if(err) throw err;
            if(result.length<1){
                stat=4;
            }   
            var password = result[0].password;
            if(password === pass){
                console.log('verified');
                stat=1;
            }
            if(password!=pass){
                stat=2;

            }
        });
    return stat;
}

Проблема в том, что console.log('verified') выполняется, когда выполняется условие. Но когда эта функция вызывается, она всегда возвращает 0

Как мне заставить его обновить переменную stat?

Ответы [ 2 ]

2 голосов
/ 11 апреля 2019

Запрос будет выполнен асинхронно. Поэтому, если вы выполните функцию, stat будет возвращен ДО того, как будет выполнен обратный вызов con.query(...). Поэтому stat всегда равен 0.

function confirm(uname, pass){
    var query = "select * from clients where name='"+uname+"' ";
    var stat = 0;
        con.query(query, function(err, result){
            // This is executed delayed. return is already called.
            if(err) throw err;
            if(result.length<1){
                stat=4;
            }   
            var password = result[0].password;
            if(password === pass){
                console.log('verified');
                stat=1;
            }
            if(password != pass){
                stat=2;

            }
        });
    return stat;
}

Чтобы решить эту проблему, вы должны использовать обратный вызов самостоятельно:

function confirm(uname, pass, cb){
    var query = "select * from clients where name='"+uname+"' ";
    var stat = 0;
        con.query(query, function(err, result){
            if(err) return cb(err);
            if(result.length < 1){
                stat=4;
            }   
            var password = result[0].password;
            if(password === pass){
                console.log('verified');
                stat=1;
            }
            if(password != pass){
                stat=2;
            } 
            cb(null, stat);
        });
}

И назовите это так:

confirm("<username>", "<pw>", function(error, stat) {
    if (error) 
    {
          // do error routine
    } else {
         // all fine, stat is set, no error thrown
    }
}
0 голосов
/ 11 апреля 2019

Это потому, что ваш оператор возврата находится за пределами обратного вызова.Попробуйте это:

var con = mysql.createConnection({
 host: "localhost",
 user: "XXXXXX",
 password: "XXXXXX",
 database: "XXXXXX"
});
con.connect(function(err){
    if(err) throw err;
});

function confirm(uname,pass){
  return new Promise((resolve, reject) => {
    var query = "select * from clients where name='"+uname+"' ";
    var stat = 0;
    con.query(query,function(err,result){
      if(err) throw err;
      if(result.length<1){
        stat=4;
      }   
      var password = result[0].password;
      if(password === pass){
        console.log('verified');
        stat=1;
      }
      if(password!=pass){
        stat=2;
      }
        resolve(stat);
    });   
  });
}

Затем, когда вы вызываете функцию, вам нужно использовать синтаксис Promise / Async.

Синтаксис Promise: confirm('yourusername', 'yourpassword').then(stat => {what to do with stat});

Синтаксис Async:let stat = await confirm('yourusername', 'yourpassword');

...