Node.js 返回的对象未使用dynamicHelpers定义
我已经创建了一个处理动态助手的外部文件,其中包括一系列我希望能够从所有视图中使用的函数 在其中一个函数中,我正在运行一个查询并从数据库中获取标记,我想在layout.jade文件中使用它(所有其他视图都在使用它)。在控制台中,一切似乎都正常。查询返回tags对象,但由于某种奇怪的原因,我无法将该对象返回到视图,这给了我一条错误消息,告诉我“tags”未定义 这是我的文件dynamicHelpers.js中的代码:Node.js 返回的对象未使用dynamicHelpers定义,node.js,express,mongoose,pug,Node.js,Express,Mongoose,Pug,我已经创建了一个处理动态助手的外部文件,其中包括一系列我希望能够从所有视图中使用的函数 在其中一个函数中,我正在运行一个查询并从数据库中获取标记,我想在layout.jade文件中使用它(所有其他视图都在使用它)。在控制台中,一切似乎都正常。查询返回tags对象,但由于某种奇怪的原因,我无法将该对象返回到视图,这给了我一条错误消息,告诉我“tags”未定义 这是我的文件dynamicHelpers.js中的代码: exports.tags = function(req, res){ va
exports.tags = function(req, res){
var environment = require('../environment');
var service = require('../service');
service.init(environment);
var model = service.useModel('tag');
var query = model.Tag.find({});
query.exec(function (err, tags) {
if (err) {
console.log(err);
// do something
}
console.log(tags);
return tags;
});
}
exports.tags = function(req, res) {
console.log(req.tags); <--- undefined
return req.tags;
};
exports.tags = function(req, res) {
return req.tags;
};
在layout.jade中,我以这种方式获取对象(显示未定义):
我实际上想做的是循环遍历所有带有“each”的标记。因此,后续问题是,这是否允许并且可能(如果“tags”未定义)
更新:
我尝试了@Linus G Thiel的解决方案(见下文),但无法使其工作(res.tags未定义)。通过中间件中的console.log(tags),它会打印出对象。但是,在下面的dynamicHelper函数中,它未定义。似乎res.tags由于某种原因没有传递给dynamicHelper
dynamicHelpers.js:
exports.tags = function(req, res){
var environment = require('../environment');
var service = require('../service');
service.init(environment);
var model = service.useModel('tag');
var query = model.Tag.find({});
query.exec(function (err, tags) {
if (err) {
console.log(err);
// do something
}
console.log(tags);
return tags;
});
}
exports.tags = function(req, res) {
console.log(req.tags); <--- undefined
return req.tags;
};
exports.tags = function(req, res) {
return req.tags;
};
exports.tags=函数(请求、恢复){
console.log(req.tags);它有点脏,但您可以这样做以等待设置标记。不过,Linus G Thiel提供的解决方案更好,因为这将阻止您的应用程序
tags: function(req, res) {
var environment = require('../environment');
var service = require('../service');
service.init(environment);
var model = service.useModel('tag');
var query = model.Tag.find({});
var _tags = false;
query.exec(function (err, tags) {
if (err) {
console.log(err);
// do something
}
console.log(tags);
_tags = tags;
});
while(_tags == false);
return _tags;
}
你这样试过吗
exports = function(app) {
app.dynamicHelpers({
tags: function(req, res) {
var environment = require('../environment');
var service = require('../service');
service.init(environment);
var model = service.useModel('tag');
var query = model.Tag.find({});
query.exec(function (err, tags) {
if (err) {
console.log(err);
// do something
}
console.log(tags);
return tags;
});
}
});
}
require("helpers")(app);
正如@Exploit所说,您的标记
函数对查询.exec进行异步调用,该调用将在标记
函数返回后完成。Express'助手
和dynamicchelpers
不能是异步的,因此您需要以某种方式对其进行重构。一种方法是在较早的时候将其置于req
上中间件或路由,然后有一个简单的dynamicHelper
,它返回:
dynamicHelpers.js:
exports.tags = function(req, res){
var environment = require('../environment');
var service = require('../service');
service.init(environment);
var model = service.useModel('tag');
var query = model.Tag.find({});
query.exec(function (err, tags) {
if (err) {
console.log(err);
// do something
}
console.log(tags);
return tags;
});
}
exports.tags = function(req, res) {
console.log(req.tags); <--- undefined
return req.tags;
};
exports.tags = function(req, res) {
return req.tags;
};
中间件(您可能不希望对所有路由执行此操作,您可以查看,例如或):
您需要在其他路由之前定义中间件
module.exports = function(app, express, next){
app.configure(function() {
app.use(function(req, res, next) {
var environment = require('./environment');
var service = require('./service');
service.init(environment);
var model = service.useModel('tag');
var query = model.Tag.find({});
query.exec(function (err, tags) {
if (err) {
return next(err);
}
req.tags = tags;
next();
console.log(req.tags); <--- works fine
});
});
// lots of more app.use functions (eg. express.cookieParser());)
// ...
});
};
module.exports=函数(应用程序、express、下一个){
app.configure(函数(){
应用程序使用(功能(请求、恢复、下一步){
var-environment=require(“./environment”);
var服务=需要(“./服务”);
service.init(环境);
var model=service.useModel('tag');
var query=model.Tag.find({});
exec(函数(错误、标记){
如果(错误){
返回下一个(错误);
}
req.tags=标签;
next();
log(req.tags);感谢您的回答。问题是dynamicHelper工作得很好,所以它不是“必需的”“问题。只是对象本身似乎没有返回。:/这可能是因为query.exec是异步的,并且函数在查询完成之前返回。问题是,使用console.log(标记)可以很好地打印对象。”,在返回之前。@JasonCraig它将显示在日志语句中,但那是在标记函数返回之后,因为query.exec
是异步的。谢谢!我已经尝试了上面的代码,但是我在req.tags上没有定义?而且您在到达路由之前使用中间件?是的,我想至少是这样。请查看我的现在更新了一个问题,解释了它现在是如何实现的。也许我做错了什么?试着在您测试的路径中执行控制台.log
,看看哪个log语句最先出现。可能是这样的情况,它在响应后获取标记。@JasonCraig——如果确实要解决这个问题:如果您有一行app.use(app.router)
,确保这是在我的示例中的中间件之后。如果没有,请确保在执行任何应用程序之前调用配置
模块。