循环遍历数组并根据先前查询的结果对数组中的每个条目执行My SQL查询

时间:2017-07-03 16:40:01

标签: javascript mysql node.js asynchronous async.js

我有一系列项目:

var myArr = ['item1', 'item2', 'item3'];

我正在尝试遍历这些项目并检查它们是否存在于我的数据库中。如果该项目不存在,那么我将其添加到数据库中。

var sql = 'Select * from DB where item="' + myArr[i] + '"';
connection.query(sql, function(e, r, f) {
    if(!e && r.length <= 0) {
        performInsertOnDB(myArr[i]);
    }
});

我的麻烦是,对变量i的引用不会保持为connnection.query是异步的。我需要等到第一次选择完成才能继续。我正在尝试使用异步库来完成此任务,但我不能完全掌握如何执行任务。

这是我到目前为止所做的:

async.each(lootArray, function(lootItem, addLootItem) {
    var sql = "SELECT * FROM loot_history WHERE date = DATE('" + moment(lootItem[1]).format('YYYY-MM-DD') + "') AND time = '" + lootItem[2] + "' AND itemId = " + lootItem[4];
    connection.query(sql, function(error, results, fields) {
        if (error) {
            sendDiscordMessage(loachannel, error + ', <@105094681141977088>');
            return false;
        } else {
            if (results.length > 0) {
                //duplicates.push(lootArray[i]);
            } else {
                addLootItem(lootItem);
            }
        }
    });
}, function(err) {
    // if any of the file processing produced an error, err would equal that error
    if (err) {
        // One of the iterations produced an error.
        // All processing will now stop.
        console.log('A file failed to process');
    } else {
        console.log('All files have been processed successfully');
    }
});

function addLootItem(lootItem) {
    var sql = "INSERT INTO loot_history SET player = " + lootItem[0] + ", date = " + moment(lootItem[1]).format('YYYY-MM-DD') + ", time = '" + lootItem[2] + ", item = " + lootItem[3] + ", itemId = " + lootItem[4] + ", itemString=" + lootItem[5] + ", response= " + lootItem[6] + ", votes= " + lootItem[7] + ", class= " + lootItem[8] + ", instance=" + lootItem[9] + ", boss=" + lootItem[10] + ", gear1=" + lootItem[11] + ", gear2=" + lootItem[12] + ", reasponseId=" + lootItem[13] + ", isAwardReason=" + lootItem[14];
    connection.query(sql, function(error, results, fields) {
        if (error) {
            sendDiscordMessage(loachannel, error + ', <@105094681141977088>');
        }
    });
}

编辑:一切正常,但回调AddLootItem没有触发。为什么这个回调没有被调用?我可以在if语句中设置日志事件,但是函数本身永远不会触发。

1 个答案:

答案 0 :(得分:2)

问题是异步回调的名称与项目不存在时要调用的函数相同。尝试将函数中的名称更改为其他名称:callback,并在if语句中调用它或将其传递给addLootItem,并在项目添加后调用它。

async.each(lootArray, function(lootItem, callback) {
    var sql = "SELECT * FROM loot_history WHERE date = DATE('" + moment(lootItem[1]).format('YYYY-MM-DD') + "') AND time = '" + lootItem[2] + "' AND itemId = " + lootItem[4];
    connection.query(sql, function(error, results, fields) {
        if (error) {
            sendDiscordMessage(loachannel, error + ', <@105094681141977088>');
            calback(err);
        } else {
            if (results.length > 0) {
                //duplicates.push(lootArray[i]);
                callback();
            } else {
                addLootItem(lootItem, callback);
            }
        }
    });
}, function(err) {
    // if any of the file processing produced an error, err would equal that error
    if (err) {
        // One of the iterations produced an error.
        // All processing will now stop.
        console.log('A file failed to process');
    } else {
        console.log('All files have been processed successfully');
    }
});

function addLootItem(lootItem, done) {
    var sql = "INSERT INTO loot_history SET player = " + lootItem[0] + ", date = " + moment(lootItem[1]).format('YYYY-MM-DD') + ", time = '" + lootItem[2] + ", item = " + lootItem[3] + ", itemId = " + lootItem[4] + ", itemString=" + lootItem[5] + ", response= " + lootItem[6] + ", votes= " + lootItem[7] + ", class= " + lootItem[8] + ", instance=" + lootItem[9] + ", boss=" + lootItem[10] + ", gear1=" + lootItem[11] + ", gear2=" + lootItem[12] + ", reasponseId=" + lootItem[13] + ", isAwardReason=" + lootItem[14];
    connection.query(sql, function(error, results, fields) {
        if (error) {
            sendDiscordMessage(loachannel, error + ', <@105094681141977088>');
        }
        done();
    });
}