在表达呈现页面之前处理数据

时间:2017-04-04 03:15:00

标签: javascript node.js express

使用node和express,我试图在响应呈现页面之前处理一些信息,但我没有运气这样做。有什么建议吗?

app.get("/Category", function (request, response) {
    if (request.query.Id) {
        // get all the posts by categoryId

        ForumPost.find({categoryId: request.query.Id}, function (err, posts) {
            if (err) throw err;

            var usernames = {};

            for (i = 0; i < posts.length; i++) {
                User.findById(posts[i].userId, function (err, user) {
                    if (err) throw err;
                    var username = user.username;
                    usernames[i] = username;
                });
            }
            response.render("Category", {
                message: posts,
                userList: usernames
            });

        });
    }
});

2 个答案:

答案 0 :(得分:0)

您实际上是在数据库中触发了很多查找。 User.findById是一个异步方法,并返回一个查询,该查询可以转换为一个promise,并最终完成。因此,当你点击

时,这些回调并没有被执行
number

在呈现某些响应后,您的响应标头将在username变量上发送或不发送正确的值。 看看Promises/A+

答案 1 :(得分:0)

您可能只想使用单个find查询数据库,并将所有用户ID作为单个$in过滤器传入,然后确保在回调处理程序中形成响应mongoose希望你作为第二个参数传入find函数:

// build the list of all ids you need
var ids = posts.map(p => mongoose.Types.ObjectId(p.userId));

// let's remove duplicates, too
ids = ids.filter((id,pos) => ids.indexOf(id)===pos);

// find all these users in a single query:
User.find({
  '_id': { $in: ids}
}, (err, users) => {
  // handle the query result

  if (err) {
    // do something error related here
    return ...
  }

  // no error: get the usernames and send the response
  var usernames = users.map(user => user.username);
  response.render("Category", {
    message: posts,
    userList: usernames
  });
});

这使用现代箭头功能,但如果您使用旧版本的Node(pre-6),则可以使用经典功能签名轻松替换它们((a,b,...) => c相当于function(a,b,...) { return c }。从技术上讲,他们是(function(a,b,...) { return c; }).bind(this),但在上面的代码中并没有相关的区别。)