Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 回调无效,回调前仍执行函数_Javascript_Mysql_Node.js_Callback - Fatal编程技术网

Javascript 回调无效,回调前仍执行函数

Javascript 回调无效,回调前仍执行函数,javascript,mysql,node.js,callback,Javascript,Mysql,Node.js,Callback,我有一个回调函数,我的问题是函数的返回发生在回调之前,然后返回null,而不是返回坐标数组 函数回调(坐标=[]){ 控制台日志(坐标); 返回坐标; } 函数getCoordinates(回调){ connection.connect(); 设坐标=[null]; connection.query('选择AreaId作为areaNumber,选择经度作为经度,选择纬度作为坐标的纬度',函数(错误、结果、字段){ 如果(错误)抛出错误; 设面积=[]; 对于(结果的结果){ 如果(!区域包含(结

我有一个回调函数,我的问题是函数的返回发生在回调之前,然后返回null,而不是返回坐标数组

函数回调(坐标=[]){ 控制台日志(坐标); 返回坐标; } 函数getCoordinates(回调){ connection.connect(); 设坐标=[null]; connection.query('选择AreaId作为areaNumber,选择经度作为经度,选择纬度作为坐标的纬度',函数(错误、结果、字段){ 如果(错误)抛出错误; 设面积=[]; 对于(结果的结果){ 如果(!区域包含(结果区域编号)){ 区域。推送(结果。区域编号) 坐标[结果区域编号]=[]; } 坐标=[结果.经度,结果.纬度]; 坐标[结果.区域编号].推送(坐标); } 坐标=回调(坐标) }); 连接。结束(); 返回坐标; } log(getCoordinates(回调)); 我有:

[null]//对应于console.log(getCoordinates(callback))

[带值数组]//对应于函数vallback中的console.log(坐标)

我的回拨将被考虑如何处理?
抱歉,我是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();