Javascript 回调无效,回调前仍执行函数
我有一个回调函数,我的问题是函数的返回发生在回调之前,然后返回null,而不是返回坐标数组 函数回调(坐标=[]){ 控制台日志(坐标); 返回坐标; } 函数getCoordinates(回调){ connection.connect(); 设坐标=[null]; connection.query('选择AreaId作为areaNumber,选择经度作为经度,选择纬度作为坐标的纬度',函数(错误、结果、字段){ 如果(错误)抛出错误; 设面积=[]; 对于(结果的结果){ 如果(!区域包含(结果区域编号)){ 区域。推送(结果。区域编号) 坐标[结果区域编号]=[]; } 坐标=[结果.经度,结果.纬度]; 坐标[结果.区域编号].推送(坐标); } 坐标=回调(坐标) }); 连接。结束(); 返回坐标; } log(getCoordinates(回调)); 我有: [null]//对应于console.log(getCoordinates(callback)) 及 [带值数组]//对应于函数vallback中的console.log(坐标) 我的回拨将被考虑如何处理?Javascript 回调无效,回调前仍执行函数,javascript,mysql,node.js,callback,Javascript,Mysql,Node.js,Callback,我有一个回调函数,我的问题是函数的返回发生在回调之前,然后返回null,而不是返回坐标数组 函数回调(坐标=[]){ 控制台日志(坐标); 返回坐标; } 函数getCoordinates(回调){ connection.connect(); 设坐标=[null]; connection.query('选择AreaId作为areaNumber,选择经度作为经度,选择纬度作为坐标的纬度',函数(错误、结果、字段){ 如果(错误)抛出错误; 设面积=[]; 对于(结果的结果){ 如果(!区域包含(结
抱歉,我是node.js上的新手,因此可能理解错误。 我想得到的是一个坐标数组,稍后我可以在我的代码中的两个不同位置使用它,比如:
.get('/map',函数(req,res){
让Coords=getCoordinate(回调)
res.render('map.ejs',{token:tokenMapbox,坐标:Coords});
})
.get('/wmap',函数(req,res){
让Coords=getCoordinate(回调)
res.render('wmap.ejs',{token:tokenMapbox,坐标:Coords});
})
你混淆了不同的东西。让我解释一下
首先,忘记“回调”这个词。我们将把它理解为作为参数传递给另一个函数的函数。别担心,我会解释的
所以我们从这个问题开始:如何从数据库中获取坐标数组并将其打印出来
接下来,您将了解与数据库交互并假设库是这样工作的:它有一个函数connection.query(myQuery,someFunction)
,可以从数据库中获取结果
现在,关于这个查询函数,首先要注意的是它的参数myQuery
是一个字符串,someFunction
是一个函数定义。虽然我们在其他语言中看到,我们将数字、字符串等值作为参数传递给函数,但有趣的是,在javascript中,您也可以将函数定义作为参数传递。这就是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...
您了解这是如何使一个有趣的函数在不同情况下有用的。如果您知道只需要doSomething()的一个实现,那么您可以简单地从参数中删除doSomething
,并执行您想执行的任何操作,您可以直接在InterestingsFunction(例如console.log(twiceOfVar))中执行该操作
现在回到查询
函数。它也是一个有趣的函数,如果您转到query
函数的定义(您可以挖掘库中的代码以查看query函数的内部内容),您会发现它对数据库执行一些操作,获取结果并调用作为参数传递的函数[类似于doSomething
],如果在执行此操作时遇到任何错误,它将调用参数中的函数并将错误传递给它
当它这样做时,它将错误、结果和字段作为参数发送回该函数。现在,您可以在作为参数传递的函数中使用这些参数。现在由您决定如何利用它,您可以简单地将结果打印如下(还记得我们是如何使用interestingJsFunction的吗?)
我把最后两个练习留给你,你应该能够在那之后解决问题。尝试console.log语句来理解这个问题有几种方法,但是如果您希望以与同步代码类似的方式使用生成的坐标,我建议您尝试使用async/await语法。如果从异步函数调用查询,则可以使用wait关键字提供更可读的代码 一旦在异步函数中填充了坐标变量,就可以随心所欲地使用它 例如:
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();
忘记返回值吧。需要使用
坐标的代码应位于回调中。这可能会有帮助:,尤其是“误解1:从回调返回”“我希望得到一个坐标数组,以后可以在代码中的两个不同位置使用。”这取决于“以后”的真正含义以及这两个位置的含义。但一般来说,将所有需要数据的代码都放在回调中会有问题。通过一个更完整的例子,我们可以更好地帮助您。一些反馈:总体上正确,但是单词的选择有点不精确。例如:“有趣的是,您不能仅将变量作为参数传递,而是可以将函数传递为PAR。
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();