使用节点(ES6)和蓝鸟保证混淆

在asynchronous调用完成之前,我有一个值被分配的问题,所以我select使用Promises(在这个例子中是Bluebird)。 我认为可以解决这个问题,但是由于我并不十分熟悉承诺/节点,所以它仍然在做同样的事情。

我将如何去修改我的代码,以正确使用承诺? 并保持一个stream程,所以我可以validation基于前row modules

 var Promise = require('bluebird'); var db = require('../shared/db'); var queryHelper = require('../shared/queryHelper'); var schemas = require('../schemas/schemas'); var _ = require('lodash'); var serverSettings = require('../shared/coreServerSettings'); // Create new instance of mysql module var connection = new db(); var queryhelper = new queryHelper(); // Promised methods var queryAndWait = Promise.promisify(connection.query); 

..snip ..

 queryAndWait(query + '; ' + queryFoundRows, params).then(function (result) { var payload = []; var site_access = []; var module_access = []; _.each(result[0], function (row) { var sites = row.site_access.split(','); _.each(sites, function (site_id) { site_access.push(site_id); }); row.site_access = site_access; site_access = []; queryAndWait(queryModules, [row.priv_id]).then(function (result) { _.each(result, function (module) { var modulePriv = { priv_name: module.priv_name, priv_num: module.priv_num, enabled: module.enabled }; module_access.push(modulePriv); }); //console.log("am assigning " + JSON.stringify(module_access)); row.module_access = module_access; module_access = [] }); payload.push(row); }); }); 

澄清:

对不起,模块是用户(行)有权访问的产品组,可以实时计算(按位 – 因此没有可用的连接和单独的查询),模块查询返回类似于以下内容的内容,然后循环访问在返回有效载荷之前附加到行:

 [{"priv_name":"INTERACT","priv_num":1,"enabled":1},{"priv_name":"STAFF_ADMIN","priv_num":32,"enabled":1},{"priv_name":"INT_EDIT","priv_num":64,"enabled":0},{"priv_name":"FAILED_LOGIN","priv_num":128,"enabled":0},{"priv_name":"INT_TAGS","priv_num":256,"enabled":0},{"priv_name":"NC","priv_num":512,"enabled":0},{"priv_name":"CC_TIMETABLE_MGR","priv_num":1024,"enabled":0}] 

是的,内部queryAndWait将独立运行的每一行,因为你不链接的承诺。

既然你使用蓝鸟,你需要这样的东西来维持stream量

 queryAndWait(query + '; ' + queryFoundRows, params).then(function (result) { return Promise.map(result[0], function (row) { var site_access = []; var module_access = []; var sites = row.site_access.split(','); _.each(sites, function (site_id) { site_access.push(site_id); }); row.site_access = site_access; return queryAndWait(queryModules, [row.priv_id]).then(function (result) { _.each(result, function (module) { var modulePriv = { priv_name: module.priv_name, priv_num: module.priv_num, enabled: module.enabled }; module_access.push(modulePriv); }); row.module_access = module_access; return row; }); }); }).then(function(payload) { console.log(payload); }).catch(function(error) { console.log(error); }); 

Promise帮助您以简单的方式控制应用程序的stream动。 我鼓励你阅读有关承诺的基本原则,至less是Promise A +规范。

你的代码可以用很多方式写,这是我推荐的方式,因为它是模块化的:

 var Promise = require('bluebird'); var queryAndWait = Promise.promisify(connection.query); function getRows(params) { return queryAndWait(query + '; ' + queryFoundRows, params) .then(function (result) { var site_access = []; _.each(result[0], function (row) { var sites = row.site_access.split(','); _.each(sites, function (site_id) { site_access.push(site_id); }); row.site_access = site_access; site_access = []; return row; }); }); } function getModules(row) { return queryAndWait(queryModules, [row.priv_id]) .then(function (result) { var payload = []; var module_access = []; _.each(result, function (module) { var modulePriv = { priv_name: module.priv_name, priv_num: module.priv_num, enabled: module.enabled }; module_access.push(modulePriv); }); row.module_access = module_access; payload.push(row); return payload; }); } getRows(params) .then(getModules) .then(function(payload) { // Do something with your payload }) 

我做了下一个:

  1. 将他自己的函数中的每个逻辑分开(为什么?因为您可以在另一个函数中重用逻辑,在另一个库中导出方法等)
  2. 我在每个function中都会返回承诺。 承诺可以嵌套,并按顺序执行。
  3. 每个实习生承诺解决价值。 getRows – >解决行,getModules – >解决有效载荷

您也可以使用promise的catch方法来pipe理erros,例如:

 getRows(params) .catch(function(err) { // Something went wrong with getRows // If i can't recovery must return a reject. }) .then(getModules) .catch(function(err) { //Something went wrong with getModules // If i can't recovery must return a reject. }) .then(function(payload) { // Do something with your payload })