为什么变量值在循环外不可用

时间:2019-12-20 15:46:38

标签: mysql node.js

我是node.js的新手,但是编程的老手。我正在从查询中获取值,并将它们放入数组中。这些值在数组创建中可用,但不能在外部创建。控制台日志“新数据”显示point [0]具有一个值。控制台日志点[0](从末端开始的第三行)显示未定义。这是我的代码。

    var polygon = [-89.72,34.27,-89.46,34.53,-89.44,34.53,-89.43,34.52];
    var point = [];
    con.connect(function (err) {
        console.log("Connected4 " + polygon);
        var sql = 'select customer_num, latitude,longitude from gc.customers';  
        console.log("SQL = " + sql);
        con.query(sql, function (err, rows, fields) {
            if (err) throw err;
            for (var i = 0; i < rows.length; i++) {       
                   point[0] = rows[i].latitude;
                   point[1] = rows[i].longitude;
                   console.log("new row " + point[0] + " newpoint " + point[1]);                                
            }                      
        });                  
        console.log("point0= ", point[0], "polygon0 = ", polygon[0])
        const inside = require("point-in-polygon")(point, polygon)
        console.log('inside = ' + inside)
    });

这是我的控制台日志

node junksql.js
Connected4 -89.72,34.27,-89.46,34.53,-89.44,34.53,-89.43,34.52
SQL = select customer_num, latitude,longitude from gc.customers
point0=  undefined polygon0 =  -89.72
inside=  false point0=  undefined vs0 =  -89.72
inside = false
new row 28.406973 newpoint -81.57685
new row 28.406973 newpoint -81.57685
new row 28.472523 newpoint -81.473743
new row 28.406973 newpoint -81.57685
new row 28.406973 newpoint -81.57685
new row 28.406973 newpoint -81.57685
new row 28.472523 newpoint -81.473743
new row 28.472523 newpoint -81.473743
^C

2 个答案:

答案 0 :(得分:0)

console.log可以清楚地看到,查询之外的所有内容都首先运行。

这就是所谓的Asynchronous behavior。这基本上意味着您无法从运行Asynchronously的函数中获取值,因为Javascript / Node.js是同步语言(单线程),并且它不会等待您async function完成并{{1} }当前持有的任何值,默认情况下为console log

人们对此行为感到很困惑,您可能想了解Event Loop

如何处理Node.J和异步内容。

答案 1 :(得分:0)

它是未定义的,因为它在import React from 'react' import App from 'next/app' import Nav from '../components/nav' class MyApp extends App { // Only uncomment this method if you have blocking data requirements for // every single page in your application. This disables the ability to // perform automatic static optimization, causing every page in your app to // be server-side rendered. // // static async getInitialProps(appContext) { // // calls page's `getInitialProps` and fills `appProps.pageProps` // const appProps = await App.getInitialProps(appContext); // // return { ...appProps } // } render() { const { Component, pageProps } = this.props return ( <> <Nav /> <Component {...pageProps} /> </> ); } } export default MyApp 的回调函数之外。这里发生的事情是您的代码不会等待回调完成,因此当它到达行con.query时,它将在评估回调块的同时移至con.query(sql, function (err, rows, fields) {。有几种解决方法。这是一个实现Promise的修复程序。

console.log("point0= ", point[0], "polygon0 = ", polygon[0]

请注意,循环遍历结果,但将值分配给const sqlQuery = (query) => { return new Promise((resolve, reject) => { con.query(query, function (err, rows, fields) { if (err) return reject(err); return resolve (rows); }); }); }; const polygon = [-89.72,34.27,-89.46,34.53,-89.44,34.53,-89.43,34.52]; let point = []; con.connect(function (err) { sqlQuery('select customer_num, latitude,longitude from gc.customers') .then(results => { for (let i = 0; i < results.length; i++) { //note: this is probably not the best logic point[0] = results[i].latitude; point[1] = results[i].longitude; } const shape = require("point-in-polygon")(point, polygon); //do stuff with, or return, shape }) .catch(err => { //handle error }); }); point[0]意味着,如果您有多个结果,则只会设置最后一对。根据您期望在此处发生的事情,有更好的方法来构造此部分。

我在这里所做的关键更改是我用Promise包裹了查询。这使我们能够确定在承诺中确切地解决或拒绝逻辑的位置。返回承诺后,您可以将point[1]async/await结合使用,也可以使用Promise.prototype.then()等待返回的值。