为什么queryAsync()会导致添加元数据?

我使用queryAsync()按问题的答案规定,它的工作原理,但它增加了很多额外的元数据到我的查询结果,否则是一个简单的查询。


以下是我用来处理/执行查询并logging结果的内容:

 var retrieveSettings = Promise.method(function (username, connection) { console.log('User ' + username + ' retrieving settings...'); var q = 'select * from sales_settings'; return connection.queryAsync(q).then(function (rows, fields) { list = []; for (x = 0; x < rows.length; x++) { list.push(rows[x]); } //console.log('Settings: ' + JSON.stringify(list, null, 4)); return list; }); }); 

这里是logging的结果:

 Settings: [ [ { "group_name": "add_auto", "commission_rate": 0, "monthly_req": 0, "category_name": "Auto", "commission_type": "none", "group_title": "Added Auto" }, { "group_name": "add_fire", "commission_rate": 0, "monthly_req": 0, "category_name": "Fire", "commission_type": "none", "group_title": "Added Fire" }, { "group_name": "bank_dep", "commission_rate": 25, "monthly_req": 0, "category_name": "Bank", "commission_type": "static", "group_title": "Bank Deposit" }, { "group_name": "bank_loan", "commission_rate": 75, "monthly_req": 8, "category_name": "Bank", "commission_type": "static", "group_title": "Bank Loan" }, { "group_name": "health", "commission_rate": 0.084, "monthly_req": 4, "category_name": "Health", "commission_type": "premium", "group_title": "Health App" }, { "group_name": "life", "commission_rate": 0.084, "monthly_req": 8, "category_name": "Life", "commission_type": "premium", "group_title": "Life App" }, { "group_name": "new_auto", "commission_rate": 0.03, "monthly_req": 32, "category_name": "Auto", "commission_type": "rate", "group_title": "Raw New Auto" }, { "group_name": "new_fire", "commission_rate": 0.03, "monthly_req": 20, "category_name": "Fire", "commission_type": "rate", "group_title": "Raw New Fire" } ], [ { "catalog": "def", "db": "officeball", "table": "sales_settings", "orgTable": "sales_settings", "name": "group_name", "orgName": "group_name", "filler1": [ 12 ], "charsetNr": 33, "length": 135, "type": 253, "flags": 20483, "decimals": 0, "filler2": [ 0, 0 ], "zeroFill": false, "protocol41": true }, { "catalog": "def", "db": "officeball", "table": "sales_settings", "orgTable": "sales_settings", "name": "commission_rate", "orgName": "commission_rate", "filler1": [ 12 ], "charsetNr": 63, "length": 13, "type": 246, "flags": 4097, "decimals": 3, "filler2": [ 0, 0 ], "zeroFill": false, "protocol41": true }, { "catalog": "def", "db": "officeball", "table": "sales_settings", "orgTable": "sales_settings", "name": "monthly_req", "orgName": "monthly_req", "filler1": [ 12 ], "charsetNr": 63, "length": 11, "type": 3, "flags": 4097, "decimals": 0, "filler2": [ 0, 0 ], "zeroFill": false, "protocol41": true }, { "catalog": "def", "db": "officeball", "table": "sales_settings", "orgTable": "sales_settings", "name": "category_name", "orgName": "category_name", "filler1": [ 12 ], "charsetNr": 33, "length": 135, "type": 253, "flags": 4097, "decimals": 0, "filler2": [ 0, 0 ], "zeroFill": false, "protocol41": true }, { "catalog": "def", "db": "officeball", "table": "sales_settings", "orgTable": "sales_settings", "name": "commission_type", "orgName": "commission_type", "filler1": [ 12 ], "charsetNr": 33, "length": 135, "type": 253, "flags": 4097, "decimals": 0, "filler2": [ 0, 0 ], "zeroFill": false, "protocol41": true }, { "catalog": "def", "db": "officeball", "table": "sales_settings", "orgTable": "sales_settings", "name": "group_title", "orgName": "group_title", "filler1": [ 12 ], "charsetNr": 33, "length": 72, "type": 253, "flags": 4097, "decimals": 0, "filler2": [ 0, 0 ], "zeroFill": false, "protocol41": true } ] ] 

为什么这个不寻常的元数据被添加到我的查询结果?

从mysql的query()返回的标准callback既返回rows又返回fields 。 你正在使用的asynchronous包装(例如,如果你Q.denodeify() )只返回一个单一的东西,所以对于具有多个参数的callback,在这种情况下[rows,fields]返回一个[param1,param2]的数组。

与此相关的是,你内部的函数只需要接受一个参数(这就是[rows,fields]的这个数组)。

看到我对这个问题的答案的第二部分作为一个例子。

你的代码应该是这样的:

 var retrieveSettings = Promise.method(function (username, connection) { console.log('User ' + username + ' retrieving settings...'); var q = 'select * from sales_settings'; return connection.queryAsync(q).then(function (results) { var rows = results[0]; // get the rows var fields = results[1]; // don't really care, but just for illustration list = []; for (x = 0; x < rows.length; x++) { list.push(rows[x]); } //console.log('Settings: ' + JSON.stringify(list, null, 4)); return list; }); }); 

而实际上,对于上面的代码,没有理由你的整个callback不能只是:

  return connection.queryAsync(q).then(function (results) { return results[0]; // get the rows }); 

看起来你正在使用蓝鸟,在这种情况下,你可以使用.spread

 var retrieveSettings = Promise.method(function (username, connection) { console.log('User ' + username + ' retrieving settings...'); var q = 'select * from sales_settings'; return connection.queryAsync(q).spread(function (rows, fields) { list = []; for (x = 0; x < rows.length; x++) { list.push(rows[x]); } //console.log('Settings: ' + JSON.stringify(list, null, 4)); return list; }); }); 

mysql模块的问题在于它不符合节点js的callback标准(err, result) 。 相反,它使用(err, result1, result2) 。 由于函数只能抛出一个exception或返回一个值,蓝鸟会返回一个[result1, result2]的数组,以避免信息丢失。

.spread就像.spread .then除非它假定实现值是一个数组,并将数组的值传递给参数。