【问题标题】:Page rendering before Promise resolves in Node, Express, mongoDB在 Node、Express、mongoDB 中 Promise 解析之前的页面渲染
【发布时间】:2020-12-18 22:28:15
【问题描述】:

我已经删除了正在工作的错误处理代码(为了简单起见)。

我有一个函数 createOrder() 在我的 MongoDB 集合中创建一条新记录:

createOrder = order => new Promise((resolve, reject) => {
    Order.create({orderId: order});
    resolve();
});

getOrders() 函数将数据库中的所有当前订单添加到数组中。

getOrders = _ => new Promise((resolve, reject) => {
    Order.find({buyerId: curUser.userId}, (err, orders) => {
        orders.map(order => order.status != 'cancelled' ? curUserOrders.push(order) : null);
    });
    resolve();
});

用于发布订单的外部 javascript 文件:

postOrder = () => {
    window.location = `/new_order/order=${JSON.stringify(itemArray)}`;
}

以及“获取”请求的节点应用程序:

app.get("/new_order/order=:order", (req, res) => {
    createOrder(JSON.parse(req.params.order))
    .then(getOrders)
    .then(_ => res.render("userprofile", {user : curUser, orders: curUserOrders}));
});

当我发布新订单时,postOrder() 函数被触发并显示"userprofile",但在我再次刷新页面之前没有显示任何订单。我还在学习承诺是如何工作的,所以我猜测问题就在那里。请帮忙:)。

【问题讨论】:

  • 将 resolve() 放入 Order.create() 和 Order.find() 中。这两个都是异步的,你的承诺会立即得到解决。
  • 另外不要忘记在resolve()中传递数据,以便在promise解决后接收。
  • 谢谢你我现在明白了:)

标签: javascript node.js mongodb express promise


【解决方案1】:

像这样使用它作为回调

createOrder = order => new Promise((resolve, reject) => {
    Order.create({orderId: order}).then(()=>{resolve});
});

【讨论】:

【解决方案2】:

Promises 用于异步操作,但您的示例立即解决了 Promise。

createOrder = order => new Promise((resolve, reject) => {
    Order.create({orderId: order});
    resolve();
});

你可以这样写创建函数:

createOrder(order).then(()=>{
   // The asynchronous operation is completed!
})

但在你的情况下会发生以下情况:

createOrder = order => new Promise((resolve, reject) => {
    //Start the asynchronous operation ....
    Order.create({orderId: order});

    //... but you just resolve the operation right away.
    resolve();
});

一个更好的例子可能是另一个函数:

getOrders = _ => new Promise((resolve, reject) => {
    Order.find({buyerId: curUser.userId}, (err, orders) => {
        orders.map(order => order.status != 'cancelled' ? curUserOrders.push(order) : null);
    });
    // You just resolve without waiting for the callback of find.
    resolve();
});

你想要什么:

getOrders = _ => new Promise((resolve, reject) => {
    Order.find({buyerId: curUser.userId}, (err, orders) => {
        orders.map(order => order.status != 'cancelled' ? curUserOrders.push(order) : null);
        // Here we call resolve inside the callback and we wait for the find method and return the orders to the getOrders().then(orders => {}) call.
        resolve(orders);
    });

});

Promise 顾名思义,它为您提供了一个承诺,即它将在未来的某个时间实现(解决)。因此,您总是希望使用 resolve 函数等待,直到所有操作都完成且没有错误。

【讨论】:

  • 感谢您的解释。我已经在 cmets 中回答了。现在详细了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-18
  • 2018-07-26
  • 1970-01-01
相关资源
最近更新 更多