2016-06-08 62 views
1

我从有我的数据库表中获取值: tables未定义的值返回,而在的NodeJS执行SQL查询

我的代码:

function listshops(callback) 
{ 
client.connection.query('select * from shop',function(err,rows){ 
    if(rows.length>0) 
    { 
    for(var i=0;i<rows.length;i++) 
    { 
     var shopIdFetched = rows[i].shopId; 
     client.connection.query('select * from image where shopId=?',shopIdFetched,function(err,data){ 
      if(data.length > 0){ 
      console.log(rows[i],data); 
      } 

     }); 

    } 

    } 

}); 
} 

但显示结果时,第一个查询显示了一个未定义的值。 enter image description here

当我给行[0]和行1取值。但是我需要实现行[i]。

+0

只要看一眼它,似乎是一个非同步的问题,你可以做一个的console.log,并检查我什么价值是什么? – John

回答

2

您误会了异步调用是如何产生的。

当你运行这部分代码时会发生什么?

 for(var i=0;i<rows.length;i++) 
    { 
     var shopIdFetched = rows[i].shopId; 
     client.connection.query(...) //these are asynchronous methods  
    } 

对于rows.length=10,它将调用client.connection.query,这是不幸的是异步方法的10倍,因此尚未执行,但它把10种异步方法事件堆栈。

之后该方法同步完成和方法中的一个指示,到数据库中的通话结束时,执行该方法,这是本

 if(data.length > 0){ 
      console.log(rows[i],data); 
     } 

然而,在这一点上,对于周期已经结束,则i=10,因此行[10]是未定义的(因为rows.length=10你有数据在rows[0]rows[9]


一种解决方法可以是把另一种方法来内范围,像这样

for(var i=0;i<10;i++) 
{ 
    x(i); 
} 

function x(i){ 
    console.log(i); 
    //this i will be same even after asynchronous paradighm 
} 

同样的事情可以写成这样

for (var i = 0; i < 10; i++) { 
    (function(i){ 
     console.log(i); 
    })(i) 
} 

在你的情况

for(var i=0;i<rows.length;i++) 
{ 
    (function(i){ 
    var shopIdFetched = rows[i].shopId; 
    client.connection.query('select * from image where shopId=?',shopIdFetched,function(err,data){ 
     if(data.length > 0){ 
     console.log(rows[i],data); 
     } 

    }); 
    })(i); 
} 

为了更好地理解,这会做相同

for(var index=0;index<rows.length;index++) 
{ 
    (function(i){ 
    var shopIdFetched = rows[i].shopId; 
    client.connection.query('select * from image where shopId=?',shopIdFetched,function(err,data){ 
     if(data.length > 0){ 
     console.log(rows[i],data); 
     } 

    }); 
    })(index); 
} 

在前面的例子中,我们只是阴影变量i用不同的变量i(如果创建了多个同名变量,一个是在最内侧的范围将被选中)

+0

我明白最新的问题。我的问题是如何解决这个问题。 –

1

你不能依靠在异步回调中使用i,因为它在调用时间处理程序时发生了更改。

你应该创建一些范围来保存迭代数据(我或行)。

随着Array.prototype.forEach

rows.forEach(row => { 
    var shopIdFetched = row.shopId; 
    client.connection.query('select * from image where shopId=?',shopIdFetched,function(err,data){ 
    if(data.length > 0){ 
     console.log(row,data); 
    } 
    }); 
}); 

随着IIFE

for (var i=0; i<rows.length; i++) { 
    !function(i) { 
    // here you can use `i`/`rows[i]` without initial issue 
    }(i); 
}