【问题标题】:variable value becomes undefined in NodeJS ExpressJS变量值在 NodeJS ExpressJS 中变得未定义
【发布时间】:2016-09-27 06:55:44
【问题描述】:

我正在使用 mysql 后端中的 ExpressJS 框架来处理 NodeJS。我在 for 循环中运行查询,然后我的循环和工作取决于查询的返回值。我对mysql查询不是很好,所以我通过for循环运行它。 问题是,由于异步 [我猜!],for 循环在查询结果出来之前很久就结束了。

这是我的代码:

function search_people_step2(user_id, search_criteria, user_friend)
{
  var first_name_friends = [];
  var last_name_friends = [];


  for(var i = 0; i < user_friend.length; i++)
  {
    con.query("SELECT first_name, second_name FROM user WHERE userid = ?", user_friend[i],function(err, rows)
   {
     if(err)
     {
       //error;
     }
     else
     {
       if(rows.length == 0)
       { 
         //nothing gets returned
       }
       else {
         console.log(rows);
         first_name_friends[i] = rows[0].first_name;
         last_name_friends[i] = rows[0].second_name;
       }
 }
 });
}

现在,我可以在查询语句中获取值(使用console.log),但是,在外部,该值变为空(未定义),因为已经计算了其余代码。

我该如何解决这个问题? 提前致谢。

【问题讨论】:

  • 你不能,除非有同步方法来执行查询。
  • 如何在JS中编写同步方法?
  • 你不能,因为它取决于 sql 实现。如果你真的想返回一些东西,你可以使用承诺......
  • @n00dl3,我不明白。你能详细说明一下吗?对不起。我对 sql 语句知之甚少...
  • 我目前正在手机上写作。回家后我会帮你更多。

标签: mysql node.js express


【解决方案1】:

我在您的代码中发现奇怪的第一件事是您没有在 SQL 查询中使用 IN 语句(尽管与您的问题没有直接关系),这意味着您发出的请求与user_friend。问题是 SQL 库是异步实现的,你无法避免。但是你可以用 Promises 优雅地处理它,这是 ES6 的特性: (我没有测试代码,但我认为它应该可以工作)

function search_people_step2(user_id, search_criteria, user_friend)
{
  return new Promise((resolve,reject)=>{
    var first_name_friends = [];
    var last_name_friends = [];
    var placeHolders=user_friend.map(()=>"?").join(",");
    con.query("SELECT first_name, second_name FROM user WHERE userid IN ("+placeHolders+")",user_friend,(err,rows)=>{
      if(err)
        reject(err);
      else{
        rows.forEach(row=>{
          first_name_friends.push(row.first_name);
          last_name_friends.push(row.second_name);
        });
        resolve({first_name_friends,last_name_friends});
      }
    });
  });
}

然后像这样调用你的函数:

search_people_step2(id,crit,friends).then(result=>{
  //handle result asynchronously as there is no choice
  console.log(result.first_name_friends);
  console.log(result.last_name_friends);
}).catch(err=>{
  //handle error
});

【讨论】:

  • 当我在结果中调用搜索函数时,我的 NodeJS 抛出错误=>(对于 > 符号).....
  • 请问具体的错误是什么?你的nodejs版本是什么?
  • 没关系。为此,我使用了一个计数器来处理请求(使其异步)并继续前进。不过,我可能需要稍后实现这个模式!
【解决方案2】:

你是对的,你的问题是 mysql 调用的异步特性。您必须为您的 search_people_step2 函数提供回调。 你可以这样改:

search_people_step2(user_id, search_criteria, user_friend, callback)

在您的函数体中,您可以使用名为async 的库来正确处理所有回调。下面是一个用法示例:

async.eachSeries(user_friend, function(item, eachCb){
    con.query("SELECT first_name, second_name FROM user WHERE userid = ?", 
       user_friend[i],function(err, rows) {
       if(err) {
         eachCb('error');
       }
       else {
         if(rows.length == 0){ 
           //nothing gets returned
           eachCb(null);
         }
         else {
           console.log(rows);
           first_name_friends.push(rows[0].first_name);
           last_name_friends.push(rows[0].second_name);
           eachCb(null);
        }
      }
   }, callback);
});

这会按顺序对数组的每个项目调用每个查询,并在完成时调用内部回调。当所有项目都被处理或发生错误时,将调用外部回调。有关更多文档,请参阅异步库。

【讨论】:

  • 什么是回调函数?你说的每个CB是什么意思?在每个回调中,我是否回调我自己的函数 search_result_....?
  • "callback" 是从调用到 search_people... 的函数。您可以将 async.eachSeries 的第三个参数替换为匿名函数 function(err) { // 一切完成后做某事 } 然后从 search_people 调用回调....; eachCb 是每个项目的回调。有关详细信息,请参阅链接文档。
【解决方案3】:
simplest solution is 

function search_people_step2(user_id, search_criteria, user_friend)
    {
      var first_name_friends = [];
      var last_name_friends = [];


      for(var i = 0; i < user_friend.length; i++)
      {
        con.query("SELECT first_name, second_name FROM user WHERE userid = ?", user_friend[i],function(err, rows)
       {
         if(err)
         {
           //error;
         }
         else
         {
           if(rows.length == 0)
           { 
             //nothing gets returned
           }
           else {
             console.log(rows);
             first_name_friends[i] = rows[0].first_name;
             last_name_friends[i] = rows[0].second_name;
           }
          if(i==user_friend.length-1){
           //do your work here which you want to perform in end
          }
     }
     });
    }

或使用异步库

var async = require('async');
var first_name_friends = [];
var last_name_friends = [];

async.series([function(cb){
function search_people_step2(user_id, search_criteria, user_friend)
{
  for(var i = 0; i < user_friend.length; i++)
  {
    con.query("SELECT first_name, second_name FROM user WHERE userid = ?", user_friend[i],function(err, rows)
   {
     if(err)
     {
       //error;
     }
     else
     {
       if(rows.length == 0)
       { 
         //nothing gets returned
       }
       else {
         console.log(rows);
         first_name_friends[i] = rows[0].first_name;
         last_name_friends[i] = rows[0].second_name;
       }
if(i==user_friend.length-1){
       cb()
      }
 }
 });
}
},function(cb){
//do your work here 
}],function(err){})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-29
    • 2017-08-03
    • 2015-12-20
    • 1970-01-01
    • 2023-03-14
    • 2018-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多