回调无效,仍在回调之前执行函数

问题描述 投票:0回答:2

我有一个带有回调的函数,我的问题是该函数的返回发生在回调广告之前,然后返回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个不同位置使用。

javascript mysql node.js callback
2个回答
0
投票
您正在混淆不同的事物。让我解释一下

[第一件事,忘记术语“回调”。我们将简单地理解为一个函数作为参数传递给另一个函数。不用担心,我要解释一下。

所以我们从问题开始:

如何从数据库中获取坐标数组并打印它

接下来您将要了解与数据库交互并假设这是您的库如何工作:它具有一个函数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" }


0
投票
有多种方法可以解决此问题,但是,如果您希望以与同步代码类似的方式使用结果坐标,建议您尝试使用async / await语法。如果您通过异步函数调用查询,则可以使用

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();

© www.soinside.com 2019 - 2024. All rights reserved.