我在javascript
中有两个函数,我想在回调中设置一个全局变量,然后从我的main函数返回它。我知道javascript本质上是异步的,那么最好的方法是什么呢?我有以下代码:
var results="";
function getData() {
var sql = require("mssql");
var dbConfig={
server:"server",
database: "db",
user:"user",
password: "pw"
}
var conn = new sql.Connection(dbConfig);
var req = new sql.Request(conn);
conn.connect(function (err){
if (err) {
console.log(err);
return;
}
req.query("SELECT * FROM table",resultsCallback)
conn.close();
});
return results;
}
function resultsCallback (err, recordset) {
var tableify = require('tableify');
if (err) {
console.log(err);
}
else {
var html = tableify(recordset);
html = html.replace('<table>','');
html = html.replace('</table>',');
results=html;
}
};
答案 0 :(得分:0)
没有正确的方法可以做到这一点,因为你想做的事情是不对的。您试图在获取之前返回一个值。并且您正在使用全局变量,这可能会对您的代码造成危险。
我理解你为什么要尝试使用全局变量来获取回调的结果,但它无法正常工作。
当您的代码return results;
执行时,SQL查询甚至尚未启动,因此返回""
。
相反,请使用Promise
:
function getData() {
return new Promise((resolve, reject) => {
var sql = require("mssql");
var dbConfig = {
server: "server",
database: "db",
user: "user",
password: "pw"
}
var conn = new sql.Connection(dbConfig);
var req = new sql.Request(conn);
conn.connect(function (err) {
if (err) {
console.log(err);
reject(err);
return;
}
req.query("SELECT * FROM table",
(err, recordset) => {
// Here we call the resolve/reject for the promise
try {
// If the results callback throws exception, it will be caught in
// the catch block
resolve(resultsCallback(err, recordset));
}
catch (e) {
reject(e);
}
}
);
conn.close();
});
})
}
function resultsCallback(err, recordset) {
var tableify = require('tableify');
if (err) {
console.log(err);
throw err;
}
else {
var html = tableify(recordset);
html = html.replace('<table>', '');
html = html.replace('</table>', '');
return html;
}
};
全局变量可能很危险,您不需要它们。承诺解决了你的问题。您可以嵌套任意数量的回调,但始终使用Promise
从resolve
返回值。这是在JavaScript中执行此操作的标准现代方法。
用法:
getData().then((data)=>{console.log("Table data:",data);})
.catch((error)=>{console.log("ERROR LOADING SQL:",error);})
或者,在async
函数中:
async function doSomethingWithData() {
console.log("Start loading data.");
const data = await getData();
console.log("Done loading data.");
// your results are in the data variable now
}