nodejs怎么同步查询数据
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nodejs怎么同步查询数据相关的知识,希望对你有一定的参考价值。
nodejs在IO处理的时候本来就是异步的,这和js引擎的原理是分不开的,如果所有耗时操作都是同步的,那么必然会堵塞当前js主线程,导致并发请求出现排队堵塞的情形。js引擎正是将耗时操作交给libuv内部的线程池来处理,这样js主线程就等着接收libuv的事件轮询回掉就可以了。 参考技术A var sqlite3 = require('sqlite3').verbose();var async = require('async');
var str = "";
var db = new sqlite3.Database('score.db', function ()
db.all("select * from score", function (err, res)
if (!err)
// console.log(JSON.stringify(res));
str = JSON.stringify(res);
console.log(str);//@1 这里输出的是有值的str
else
console.log(err);
);
);
console.log(str+"jjjj");//@2 这里输出的Str,是没有值的空的
下面是输出结果:
jjjj 这是@2console打印的,Str是空的
["id":1,"name":"jim","score":"100","id":2,"name":"tom","score":"200"]
这是@1 console打印的,str是有值的。
请问怎样让查询回调先执行,让str获得值,传递出来,然后再执行最后一句@2的打印语句。javascript的异步回调真令人头痛啊,一直不知道怎么解决。
NodeJS mysql同步查询
【中文标题】NodeJS mysql同步查询【英文标题】:NodeJS mysql sync query 【发布时间】:2017-12-16 19:09:30 【问题描述】:我想像这样在 nodejs 中运行同步查询...
for (var i in data)
conn.query("Select 1 from user where userid="+data[i].id,function(err,row)
Rows.push(row);
);
console.log(Rows);
在这段代码中,我的行一直都为空...我想运行同步查询
【问题讨论】:
【参考方案1】:你可能无法在线程阻塞的意义上同步使用这样的函数(你也不应该!)但如果你使用数据库连接的承诺版本(使用 Bluebird 的 promisifyAll 或特定的在 npm 上可用的 mysql 驱动程序的 promise 版本)和新的 async/await 语法(或基于生成器的协程,用于比 Node 7.x 更早的平台,其中 async/await 不可用 - 另一种选择是使用 Babel 进行转译)。
示例 - 您可以使用这样的代码:
for (var i in data)
let row = await conn.query("Select 1 from user where
userid="+data[i].id);
Rows.push(row);
console.log(Rows);
但如果它可以并行运行,那么这样的事情会更高效、更短:
let Rows = await Promise.all(data.map(item =>
conn.query("Select 1 from user where userid=" + item.id));
console.log(Rows);
有关该主题的更多详细信息,请参阅:
Do async in a blocking program language way? Using async/await + Bluebird to promisifyAll try/catch blocks with async/await Using acyns/await in Node 6 with Babel jQuery: Return data after ajax call success注意 - 它只能在使用 async
关键字声明的函数内部使用。
警告:您的代码可能容易受到 SQL 注入攻击。您应该在 SQL 中使用占位符而不是字符串连接。我没有修复您代码的这方面 - 有关更多详细信息,请参阅这些答案:
cannot use backtick when using nodejs 7.3.0 Node.js - The multi part could not be bound How to escape mysql special characters with sockets.io/node.js/javascript Node js - Promise Rejection Warning when process a lot of data Is it possible to listen for object instantiation in Node.js?【讨论】:
【参考方案2】:您应该使用bluebird
npm
module
来解决这个问题。使用npm install bluebird
安装bluebird
var Promise = require('bluebird');
var Rows= [];
data.forEach(function (obj)
conn.query("Select 1 from user where userid="+obj.id,function(err,row)
Rows.push(row);
);
);
return Promise.all(Rows);
)
【讨论】:
这行不通。您在 forEach 回调中返回Promise.all(Rows)
,该回调在每次迭代时运行一次,并忽略其返回值。此外,您正在一个不包含承诺的数组上运行Promise.all
。无论如何,它应该做什么?【参考方案3】:
你也可以使用异步模块。
var async= require('async')
async.eachSeries(arr, function(index, callback)
conn.query("Select 1 from user where userid="+index,
function(err,res)
if (err)
return console.error('error running query', err);
else
Row.push(res);
callback();
);
,function(err)
if(err)
return err;
console.log("all queries executed")
);
【讨论】:
【参考方案4】:您可以制作一个返回 Promise 的包装器。使用await
可以使其同步:
function promiseWrapper()
return new Promise((resolve, reject) =>
conn.query("SQL_QUERY", queryCallback(resolve, reject);
function queryCallback(err, row)
return (resolve, reject)
resolve(row);
【讨论】:
以上是关于nodejs怎么同步查询数据的主要内容,如果未能解决你的问题,请参考以下文章