管理异步并在节点中执行多个MySQL查询

时间:2016-03-12 00:22:41

标签: javascript node.js asynchronous

我遇到了处理nodejs异步性质的一些问题。我正在使用nodejs-mysql连接器来获取数据。实质上,下面的代码执行查询以获取file_url并将信息发送到myApi。应该在使用api(inputId)返回的结果更新数据库之后立即运行第二个查询。但是,前者不能正常工作(连接在处理所有内容之前关闭)。使用async模块进行以下操作的最佳方法是什么?

var mysql = require("mysql");
var async = require("async");
var Q = require('q'),
    myApi = require('myApi')('xxxxx');

//DB
var con = mysql.createConnection({
    host: "localhost",
    user: "root",
    password: "root",
    database: "test"
});


//1ST Query - Fetch Urls, then upload file to api
con.query('SELECT file_url, file_id FROM myfiles', function(err, rows) {
    if (err) throw err;
    for (var i = 0; i < rows.length; i++) {

        // File URL for upload
        var fileUrl = rows[i].file_url,
            createInputPromise, createEncodingProfilePromise;
        var fileId = rows[i].file_id;

        // Create myApi Input
        createInputPromise = myApi.input.create(fileUrl);

        //WHERE THE ACTION OCCURS!
        Q.all([createInputPromise, createEncodingProfilePromise]).then(
            function(result) {
                console.log('Successfully uploaded file: ' + result[0].url + ' inputId: ' + result[0].inputId);

                //2ND Query - Save the inputId return by api for each file
                con.query(
                    'UPDATE myfiles SET myApi_input_id = ?  WHERE file_id = ?', [result[0].inputId, fileId],
                    function(err, result) {
                        if (err) throw err;
                        console.log('Changed ' + result.changedRows + ' rows');
                    }
                );

            },
            function(error) {
                console.log('Error while uploading file to api:', error);
            }
        );
    };

});

con.end(function(err) {});

3 个答案:

答案 0 :(得分:2)

发布的答案是很好的选择,但我最终希望通过使用async来完成它。我遇到了waterfall模式:

  

运行一系列函数,每个函数都将结果传递给   数组中的下一个。但是,如果任何函数传递错误   回调,下一个函数没有执行和主   立即调用带有错误的回调。

我结束了以下的实施:

var pool = mysql.createPool({...});

function fn(callback) {
    var getConnection = function(callback) {...};

    async.waterfall([
        doQuery.bind(null, getConnection),
        doSomethingAsyncWithResult,
        doUpdate(null, getConnection)
    ], function(err, result) {
        getConnection.end();
        callback(err, result);
    });

}

function doQuery(connection, callback) {
    connection.query(sql, callback);
}

function doSomethingAsyncWithResult(result, callback) {
    ...something...
    callback(null, anotherResult);
}

function doUpdate(connection, result, callback) {
    connection.update(sql, [result], callback);
}

答案 1 :(得分:0)

这很大程度上取决于您处理这些问题的方式:createInputPromisecreateEncodingProfilePromise。与这两个相关的更多代码将有助于获得良好的答案。在代码的确切位置,您会遇到问题吗? console.log('Successfully uploaded file: ' + result[0].url + ' inputId: ' + result[0].inputId);是否输出到控制台,或者之前是否有错误?

现在,您确定myApi.input.create(fileUrl)正在回复承诺吗?您需要查看该API的文档以确保它是。如果没有,那么您可以使用Q库创建一个:

&#13;
&#13;
var inputPromise = Q.defer();
var encodingProfilePromise = Q.defer();

inputPromise.resolve(myApi.input.create(fileUrl));
encodingProfilePromise.resolve(/*encoding profile code*/);

Q.all([inputPromise.promise, encodingProfilePromise.promise]).then(function(result) {
  /*blah blah blah*/
});
&#13;
&#13;
&#13;

有了更多信息,我可以提供更准确的答案。

答案 2 :(得分:0)

而不是异步模块,我会以一种不同的方式看待它。让我们选择发电机。

var fullNum = stringArray.join("") * 1