【问题标题】:Is it possible to put a render function inside a for loop in express?是否可以在 express 中将渲染函数放入 for 循环中?
【发布时间】:2019-12-06 04:42:54
【问题描述】:

所以我在通过 for 循环后渲染网页,但问题是当我将渲染放入 for 循环时,同一个页面会被多次渲染,这最终给了我错误:

Cannot set headers after they are sent to the client

^^ 这会使我的应用程序崩溃。

如果我将我的渲染放在 for 循环之外,我正在拉取的数据将无法拉取。

router.get('/dashboard', (req, res) =>
{
const roomArr = [];

model.findById(req.session.userLogin._id)
.then((user) =>
{

    user.bookedRooms.forEach((eachRoom) =>
    {
        console.log(eachRoom);

        roomModel.findById(eachRoom)
        .then((roomInfo) =>
        {
            console.log(roomInfo);
            console.log(`Rooms Array: ${roomArr}`);
            roomArr.push(roomInfo); 
        })
        .catch((err) =>
        {
            console.log(`Could not book rooms: ${err}`);
        })
    })

    res.render('registration/dashboard', {
        rooms: roomArr,
        ttl: title,
        sty: style
    })

})

})

^^ 如我上面的代码所示,我的目标是在我的会话中提取bookedRooms(array) 的id,然后检查该id 是否与房间集合中的roomsID 匹配。如果这 2 个 id 匹配,则表示用户已预订房间。

我遇到的问题是我的房间没有被拉出,我认为这可能是因为我的 render 不在我的 .then 之后。

我想我的主要问题是我的 render 必须在我的 .then 之后吗??

【问题讨论】:

  • user 是我的数据库模型,bookedRooms 是我的 mongoDB 集合中的一个数组
  • 每个请求只能调用一次res.render(),因为它会发送响应,并且每个 http 请求只能发送一个响应。在我看来,您需要收集所有数据,然后仅当您拥有所有数据并拥有一个接受数据数组的模板时才调用 res.render()
  • 这就是我上面所做的,我只是错过了推送部分。所以我收集了所有预订的房间,然后将它们推入 roomArr 数组,以便该数组包含所有预订的房间。然后在代码的最后我做一个渲染......
  • 好吧,您无需等待所有收集完成后再致电res.render(),因此您在收集任何房间之前致电res.render()。无论如何,很高兴 JaromandaX 向您展示了如何做到这一点。
  • 你知道我如何用我的代码解决这个问题吗?因为如果我可以使用数组找出它,我可以检查房间是否在数组内,然后我可以阻止用户多次预订同一个房间

标签: javascript node.js express handlebars.js


【解决方案1】:

假设 user.bookedRooms 是一个常规的 Javascript 数组

如下操作

router.get('/dashboard', (req, res) => 
    model.findById(req.session.userLogin._id)
    .then(user => Promise.all(user.bookedRooms.map(eachRoom => roomModel.findById(eachRoom))))
    .then(rooms => res.render('registration/dashboard', {
        rooms,
        ttl: title,
        sty: style
    }))
    .catch(err => console.log(`Could not book rooms: ${err}`))
)

解释:

  1. model.findById(req.session.userLogin._id) - 做之前做的事
  2. 在 ... 返回的 Promise 数组上使用 Promise.all
  3. user.bookedRooms.map 其中,对于每个 eachRoom 返回由
  4. 返回的承诺
  5. roomModel.findById(eachRoom) ... 到目前为止这么好?
  6. 一旦所有承诺解决,结果在rooms.then(rooms
  7. res.render('registration/dashboard', ... 等等,执行您在代码中所做的操作

我使用rooms作为结果的名称,以缩短

res.render('registration/dashboard', {
    rooms: roomsArr,
    ttl: title,
    sty: style
})

res.render('registration/dashboard', {
    rooms,
    ttl: title,
    sty: style
})

【讨论】:

  • 评论不用于扩展讨论;这个对话是moved to chat
  • @SamuelLiew cmets 对于得到答案很重要正确虽然
猜你喜欢
  • 2016-11-25
  • 1970-01-01
  • 2023-02-26
  • 2016-03-14
  • 2020-09-21
  • 1970-01-01
  • 2017-12-26
  • 2014-01-15
  • 1970-01-01
相关资源
最近更新 更多