我的nodeJS代码不是异步的

时间:2017-01-19 11:01:16

标签: javascript mysql node.js asynchronous

使用nodeJS包color-namer我用颜色名称命名十六进制代码。 (例如:"#FF0000"将转为"红色")

我的所有十六进制代码都存储在mysql数据库中(table = hex_codes; colname = color),我从nodejs查询。 逐行I然后检索十六进制代码的名称(colname = color),并将结果转储到另一个表(table = color_names)。

我的代码如下:

var mysql = require("mysql"),
    namer = require('color-namer'),
    connection = mysql.createConnection({
        multipleStatements: true,
        host     : '***',
        user     : '***',
        password : '***',
        database : '***'
    });


connection.connect();

    connection.query(
        `SELECT color from hex_codes`, 
        function(err, results, fields) {
            results.forEach(function(elem){
                var currentHex = elem['color'],
                    currentColor = namer(currentHex);
                connection.query(
                    `INSERT INTO color_names (hex, basic) VALUES (?,?);`, 
                    [currentHex,currentColor['basic'][0]['name']]               
                );  
            });
        }
    );

由于javascript是一种异步语言,为什么我的行不会逐个转储,但是一旦脚本运行完毕就会转储整个数据帧?

3 个答案:

答案 0 :(得分:1)

第一个connection.query的回调足以证明它的异步,并且只有在堆栈为空时才执行回调。所以在得到结果之后你正在做一个一个插入,但除了把回调放到第二个你永远不会得到它的异步或同步,因为它会很快尝试

 connection.query(
    `SELECT color from hex_codes`, 
    function(err, results, fields) {
       results.forEach(function(elem){
            var currentHex = elem['color'],
                currentColor = namer(currentHex);
            console.log("in loop");
            connection.query(
                `INSERT INTO color_names (hex, basic) VALUES (?,?);`, 
                [currentHex,currentColor['basic'][0]['name']]               
            ,function(err,data){
            console.log("insert callback")
          });  
       });
    });

执行的顺序会说它是异步的。重要的是要记住回调仅在堆栈为空时执行。

答案 1 :(得分:0)

仅在流的情况下逐个转储行。 一旦第一个项目到达,Streams就会开始发出输出。它是事件发射器模式的扩展。

但是,如果使用回调,则代码将是异步的,但结果将立即到达。

希望这有帮助

答案 2 :(得分:0)

您的代码示例中的操作应该是顺序的。方法如下:

results.forEach(function(elem){
    var currentHex = elem['color'],
    currentColor = namer(currentHex);
    connection.query(
        `INSERT INTO color_names (hex, basic) VALUES (?,?);`, 
         [currentHex,currentColor['basic'][0]['name']]               
    );  
});

这里,forEach语句的作用是将查询委托给连接对象,但不会等待查询完成。一切都好。

但是,默认情况下,connection.query方法仅支持顺序执行,这意味着查询中后续的插入请求将按顺序执行,而不是并行执行。 mysqljs文档说:

  

MySQL协议是顺序的,这意味着您需要多个连接来并行执行查询。

要使它们并行执行,您应该使用描述为here的连接池。