pipe理asynchronous性并在节点中执行多个MySQL查询

nodejs了一些处理nodejs的asynchronous性质的nodejs 。 我正在使用nodejs-mysql连接器来获取数据。 本质上,下面的代码正在执行查询来获取file_url并将信息发送到myApi。 第二个查询应该在从api( inputId )返回的结果更新数据库之后运行。 但是,以前没有工作做它的asynchronous方式(连接之前closures处理一切)。 使用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) {}); 

发布的答案是很好的select,但我最终希望得到它与async使用完成。 我遇到了瀑布模式:

运行一系列函数,每个函数都将结果传递给数组中的下一个。 但是,如果任何函数将错误传递给callback,则不会执行下一个函数,并立即调用主callback并返回错误。

我结束了以下的实施:

 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); } 

很多这取决于你如何处理这些: createInputPromisecreateEncodingProfilePromise 。 更多关于这两个代码的代码将有助于一个好的答案。 在代码中的确切位置是否会遇到问题? 是否console.log('Successfully uploaded file: ' + result[0].url + ' inputId: ' + result[0].inputId); 输出到控制台,还是之前有错误?

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

 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*/ }); 

而不是asynchronous模块,我会以不同的方式看待它。 让我们去发电机。

 let co = require('co'); let parallel = require('co-parallel'); let sequelize = require('sequelize'); // also read documentation to provide connection details (this is just pseudocode) let gen = function*() { let inputId = yield fetch_file_url(); // this function should be generator or should return promise let res = yield sequelize.query(`INSERT INTO... ${inputId} `); } co(function*() { let files = ['f1', 'f2', 'f3']; let gens = files.map(file => gen(file)); let arrayOrResults = yield parallel(gens, 5); // 5 threads // done }).catch(function(err) { // catch errors });