在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); } }); } } }); }
但是当显示结果时,第一个查询显示一个未定义的值。
当我给行[0]和行1的值正在提取。 但是我需要实现行[我]。
你误解了如何asynchronous调用。
当你运行这部分代码时会发生什么?
for(var i=0;i<rows.length;i++) { var shopIdFetched = rows[i].shopId; client.connection.query(...) //these are asynchronous methods }
对于rows.length=10
,它将调用10次client.connection.query,这是不幸的asynchronous方法,因此它还没有执行,但它把10个asynchronous方法放到事件堆栈。
这个方法同步完成后,其中一个方法指示,数据库调用完成,方法执行完毕,就是这样
if(data.length > 0){ console.log(rows[i],data); }
然而在这一点上,for循环已经完成了, i=10
,因此rows [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); }
在前面的例子中,我们只是用variablesi
映射variablesi
(如果有更多的同名variables被创build,那么将会select最内层的variables)
你不能依靠i
在asynchronouscallback,因为它是在调用时间处理程序更改。
你应该创build一些范围来保存迭代数据(我或者行)。
用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); }