我有一个带有回调的函数,我的问题是该函数的返回发生在回调广告之前,然后返回null而不是返回坐标数组
function callback(coordinates=[]){
console.log(coordinates);
return coordinates;
}
function getCoordinates(callback){
connection.connect();
let coordinates=[null];
connection.query('SELECT AreaId AS areaNumber, longitude AS longitude, latitude AS latitude FROM coordinates', function (error, results, fields) {
if (error) throw error;
let area=[];
for (result of results) {
if (!area.includes(result.areaNumber)){
area.push(result.areaNumber)
coordinates[result.areaNumber]=[];
}
coordinate=[result.longitude,result.latitude];
coordinates[result.areaNumber].push(coordinate);
}
coordinates=callback(coordinates)
});
connection.end();
return coordinates;
}
console.log(getCoordinates(callback));
我有:
[null] //对应于console.log(getCoordinates(callback));
和
[[具有值的数组] // //对应于函数vallback中的console.log(coordinates)
将考虑如何处理我的回叫?抱歉,我是node.js的新手,所以我可能会误会回调。我想要的是获得一个坐标数组,以后可以在代码的2个不同位置使用。
[第一件事,忘记术语“回调”。我们将简单地理解为一个函数作为参数传递给另一个函数。不用担心,我要解释一下。
所以我们从问题开始:
如何从数据库中获取坐标数组并打印它
接下来您将要了解与数据库交互并假设这是您的库如何工作:它具有一个函数connection.query(myQuery, someFunction)
,可以从数据库中获取结果。 现在,您注意到该查询功能的第一件事是它的参数。 myQuery
是变量(字符串),someFunction
是函数。有趣的是,您不仅可以将变量作为参数传递,还可以将函数作为参数传递。这就是使javascript功能强大的原因,您可以将函数作为参数进行传递。
哇,将函数作为参数传递,但是它如何工作?让我们举一个不同的例子。假设在这里我想创建一个函数来进行一些计算
//Here myVar is a variable and doSomething is a function
function interestingJsFunction(myVar, doSomething){
var twiceOfVar = 2*myVar;
doSomething(twiceOfVar);
var thriceOfVar = 3*myVar;
doSomething(thriceOfVar);
}
那么这个功能做什么?它应用了一些计算,并在某些时候调用了doSomething函数。一方面,它传递了myVar值的两倍以起作用;另一方面,它传递了myVar值的三次。但是,此功能doSomething
的功能目前尚未定义。您可以通过传递自己的函数作为参数来定义它。这给您无限的可能性。怎么样?
interestingJsFunction(2, function(result){ console.log(result) }) interestingJsFunction(2, function(result){ console.log("the new behaviour" + result) }) //And so on...
您了解这如何使一个有趣的JsFunction在不同情况下有用。如果您知道只需要doSomething()的一种实现,则可以简单地从参数中删除doSomething
,然后执行任何操作,就可以直接在有趣的JsFunction内部完成此操作(例如console.log(twiceOfVar))现在返回
query
功能。这也是一个有趣的JsFunction,如果您转到query
函数的定义(您可以挖掘库的代码以查看查询函数中的内容),您会发现它对数据库做了一些操作,获取了结果并调用作为参数传递的函数[类似于doSomething
],如果在执行过程中遇到任何错误,则会调用参数中的函数并将错误传递给它。[这样做时,它会将错误,结果和字段作为参数发送回此函数。因此,现在您可以在作为参数传递的函数中利用这些参数。现在由您决定如何利用它,可能是您可以简单地按如下所示打印结果(还记得我们如何使用趣味的JsFunction吗?)
//We could simply print the results if there are any connection.query(myQuery, function(error, results, fields){ if(results) console.log(results.toString()) }) //Or we could throw erorr if there's any connection.query(myQuery, function(error, results, fields){ if(error) throw error }) //Guess what would happen when you return something inside this function? connection.query(myQuery, function(error, results, fields){ return "return of query function" }) //And guess what would happen when you have something like this function myNewFunction(){ var x = connection.query(myQuery, function(error, results, fields){ return "return of query function" }) return "return of myNewFunction" }
await关键字提供更具可读性的代码。
一旦在异步函数中填充了坐标变量,就可以使用它进行所需的操作。例如:
function getCoordinates() {
connection.connect();
let coordinates = [];
return new Promise((resolve, reject) => {
connection.query('SELECT AreaId AS areaNumber, longitude AS longitude, latitude AS latitude FROM coordinates', function (error, results, fields) {
if (error) {
reject(error);
} else {
let area=[];
for (result of results) {
if (!area.includes(result.areaNumber)){
area.push(result.areaNumber)
coordinates[result.areaNumber]=[];
}
coordinate=[result.longitude,result.latitude];
coordinates[result.areaNumber].push(coordinate);
}
resolve(coordinates);
connection.end();
}
});
})
}
async function testCoordinates() {
let coordinates = await getCoordinates();
console.log("Coordinates:", coordinates);
// You can do whatever you wish with the coordinates variable
}
testCoordinates();