【问题标题】:Promise { <pending> } error even after reaching to then() block [duplicate]Promise { <pending> } 即使在到达 then() 块后也会出错 [重复]
【发布时间】:2019-08-18 17:01:03
【问题描述】:

我正在使用 nodejs 和 mongodb 开发一个小型购物网站。我已经能够从我的数据库中存储和检索数据。但是,我无法让这个应该从用户购物车中检索产品的特定功能工作。产品被检索到 then() 块中,但是当我尝试通过在产品中执行某些操作来返回或打印产品时,我得到的输出为 Promise { pending }。

在将此问题标记为重复之前(不是,但如果您认为是),至少帮我解决这个问题。

const productIds = this.cart.items.map(eachItem => {
    return eachItem.pid;
});  //to get product IDs of all the products from the cart
const cartData = db.collection('products') //db is the database function and works fine
    .find({_id: {$in: productIds}})
    .toArray()
    .then(products => {
        console.log(products); //all the products are printed correctly
        products.map(eachProduct => { 
            return {
                ...eachProduct,
                quantity: this.cart.items.find(eachCP => {
                    return eachCP.pid.toString() === eachProduct._id.toString()                            
                }).quantity //to get the quantity of that specific product (here eachProduct)
            };
        })
    })
    .catch(err => {
        console.log(err);
    });
console.log('cartData: ', cartData); //but here it prints Promise /{ pending /}

我不明白为什么我得到 Promise { } 作为输出,尽管我在 then() 块中成功地从数据库中获取了数据。 抱歉,顺便说一句凌乱的代码。我是 mongodb 新手,对 Promise 也不太了解。

【问题讨论】:

  • 您的console.log('cartData: ', cartData); 在promise 解析之前和.then() 处理程序被调用之前运行。 Promise 不会阻塞。 .then() 不会阻止。他们只是注册将在未来某个时间被调用的回调,然后你的代码的下一行(你的console.log())在.then()处理程序被调用之前很久就执行了。
  • 嘿@jfriend00 谢谢我明白你所说的。但是我没有打印,而是返回了 cartData 并尝试在另一个函数中检索数据,但我仍然无法获得它所说的数据 undefined,我没有得到它。

标签: node.js mongodb promise


【解决方案1】:

Promise#then 不会“等待”,因为程序中的下一条语句将延迟到承诺完成。

它“等待”只是因为你传递给then 的回调的执行被延迟到承诺完成。

但是您当前的功能(设置then 的功能)不会阻塞并会立即继续运行。这意味着您传递给 then 的函数之外的所有内容都可能会看到仍处于未完成状态的 Promise。

您可能想要使用async/await 构造,如链接的重复线程中所述(例如)。

【讨论】:

  • 看到处于待处理状态的承诺,事实上;在当前事件循环完成之前不会调用回调。
  • @jonrsharpe。真的。但是 promise 可能已经在函数顶部或中间的其他非异步代码完成(当然不是这里的情况)。
  • 是的,直到下一个事件循环才会调用回调,即使 promise 恰好已经完成。因此,无论如何,下面的代码将始终在回调之前运行。
  • 是的,您可以使用then 块中的承诺结果。但console.log('cartData: ', cartData) 不在该块之外。把它移进去,它会正确打印。
  • @testid123 请记住,then() 调用的返回值不是回调的返回值。这是回调结果的新承诺,因为回调尚未运行。
猜你喜欢
  • 2016-12-25
  • 1970-01-01
  • 2013-05-14
  • 1970-01-01
  • 2021-11-25
  • 2021-04-21
  • 2014-08-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多