节点异步执行
node executes asynchronously
在我的 Express 应用程序中,我使用 node_acl
实现 ACL
我的 acl.js 看起来像:
var mongoose = require('mongoose'),
node_acl = require('acl'),
acl;
mongoose.connect('mongodb://127.0.0.1:27017/aclExample', function _mongo_connected(){
var mongoBackend = new node_acl.mongodbBackend(mongoose.connection.db, 'acl_');
acl = new node_acl(mongoBackend);
console.log("ACL: ",acl);
});
set_roles();
function set_roles() {
//set permissions for roles
acl.allow([
{
roles: 'a', //roles
allows: [
{resources: '/fe', permissions: ['put', 'delete']},
] //permissions
},
{
roles: 'b',
allows: [
{resources: '/fe/api', permissions: 'post'}
]
},
{
roles: 'c',
allows: [
{resources: '/', permissions: ['post', 'put']}
]
},
{
roles: 'd',
allows: [
{resources:'/fe', permissions: ['get', 'post']}
]
}
]);
acl.addUserRoles(420, 'b').then( ()=> console.log('added user'))
.catch(err => console.error(err));
acl.addUserRoles(520, 'a').then( ()=> console.log('added user'))
.catch(err => console.error(err));
//acl.isAllowed(userId, reso, pem);
}
module.exports = acl;
和我的 app.js:
var acl = require('@root/fe-server/middlewares/fe.middleware.acl.js');
var express = require('express');
var app = express();
console.log("ACL: ",acl);
我得到的输出如下所示:
ACL: undefined
added user
added user
我可以理解节点在建立连接和创建数据库之前在 app.js 中执行控制台语句,但我似乎无法弄清楚如何解决这个问题。
任何帮助将不胜感激。
正如您自己所说,mongoose.connect
需要一些时间,因此它接受一个回调函数,一旦完成就会执行,您已经在使用它了。
在该回调函数中,您创建了 acl
资源,这意味着任何使用 acl
变量的内容也必须从该回调中执行(直接或间接)。所以在你的情况下你必须做这样的事情:
acl.js
const mongoose = require('mongoose');
const node_acl = require('acl');
const connect = (callback) => {
mongoose.connect('mongodb://127.0.0.1:27017/aclExample', (err) => {
if (err) return callback(err);
const mongoBackend = new node_acl.mongodbBackend(mongoose.connection.db, 'acl_');
const acl = new node_acl(mongoBackend);
set_roles(acl).then(() => callback(null, acl)).catch(callback);
});
};
const set_roles = (acl) => {
acl.allow([ /* stuff */ ]);
return Promise.all([
acl.addUserRoles(420, 'b').then(() => console.log('added user b')),
acl.addUserRoles(520, 'a').then(() => console.log('added user a')),
])
};
module.exports = connect;
main.js:
var connectACL = require('acl.js');
var express = require('express');
var app = express();
connectACL((err, acl) => {
console.log('ACL: ', acl);
});
重要的变化是 require('acl.js')
现在 returns 一个接受回调的函数,这样您就可以在创建后安全地使用 acl
。
您还可以看到 acl
使用另一种处理异步性的方法,称为 "Promises"(.then
和 .catch
的东西)。两者都是有效的选项,但您通常希望决定只使用一个并尽快转换另一个(就像我在这里使用 .then(() => callback(null, acl)).catch(callback)
所做的那样)。
但是,当您处理异步函数时,您将需要其中之一,因为您已确保您的代码以正确的顺序执行。
在我的 Express 应用程序中,我使用 node_acl
实现 ACL我的 acl.js 看起来像:
var mongoose = require('mongoose'),
node_acl = require('acl'),
acl;
mongoose.connect('mongodb://127.0.0.1:27017/aclExample', function _mongo_connected(){
var mongoBackend = new node_acl.mongodbBackend(mongoose.connection.db, 'acl_');
acl = new node_acl(mongoBackend);
console.log("ACL: ",acl);
});
set_roles();
function set_roles() {
//set permissions for roles
acl.allow([
{
roles: 'a', //roles
allows: [
{resources: '/fe', permissions: ['put', 'delete']},
] //permissions
},
{
roles: 'b',
allows: [
{resources: '/fe/api', permissions: 'post'}
]
},
{
roles: 'c',
allows: [
{resources: '/', permissions: ['post', 'put']}
]
},
{
roles: 'd',
allows: [
{resources:'/fe', permissions: ['get', 'post']}
]
}
]);
acl.addUserRoles(420, 'b').then( ()=> console.log('added user'))
.catch(err => console.error(err));
acl.addUserRoles(520, 'a').then( ()=> console.log('added user'))
.catch(err => console.error(err));
//acl.isAllowed(userId, reso, pem);
}
module.exports = acl;
和我的 app.js:
var acl = require('@root/fe-server/middlewares/fe.middleware.acl.js');
var express = require('express');
var app = express();
console.log("ACL: ",acl);
我得到的输出如下所示:
ACL: undefined
added user
added user
我可以理解节点在建立连接和创建数据库之前在 app.js 中执行控制台语句,但我似乎无法弄清楚如何解决这个问题。 任何帮助将不胜感激。
正如您自己所说,mongoose.connect
需要一些时间,因此它接受一个回调函数,一旦完成就会执行,您已经在使用它了。
在该回调函数中,您创建了 acl
资源,这意味着任何使用 acl
变量的内容也必须从该回调中执行(直接或间接)。所以在你的情况下你必须做这样的事情:
acl.js
const mongoose = require('mongoose');
const node_acl = require('acl');
const connect = (callback) => {
mongoose.connect('mongodb://127.0.0.1:27017/aclExample', (err) => {
if (err) return callback(err);
const mongoBackend = new node_acl.mongodbBackend(mongoose.connection.db, 'acl_');
const acl = new node_acl(mongoBackend);
set_roles(acl).then(() => callback(null, acl)).catch(callback);
});
};
const set_roles = (acl) => {
acl.allow([ /* stuff */ ]);
return Promise.all([
acl.addUserRoles(420, 'b').then(() => console.log('added user b')),
acl.addUserRoles(520, 'a').then(() => console.log('added user a')),
])
};
module.exports = connect;
main.js:
var connectACL = require('acl.js');
var express = require('express');
var app = express();
connectACL((err, acl) => {
console.log('ACL: ', acl);
});
重要的变化是 require('acl.js')
现在 returns 一个接受回调的函数,这样您就可以在创建后安全地使用 acl
。
您还可以看到 acl
使用另一种处理异步性的方法,称为 "Promises"(.then
和 .catch
的东西)。两者都是有效的选项,但您通常希望决定只使用一个并尽快转换另一个(就像我在这里使用 .then(() => callback(null, acl)).catch(callback)
所做的那样)。
但是,当您处理异步函数时,您将需要其中之一,因为您已确保您的代码以正确的顺序执行。