【问题标题】:Async await result异步等待结果
【发布时间】:2021-04-19 16:49:43
【问题描述】:

目前正处于职业过渡期,我正在从事一个研究项目,我必须在其中创建一种迷你论坛。我为我的数据库使用了 node.js/express 和 sequelize。 在下面的代码中,我的 API 尝试检索最后 10 条消息(带有分页内容)发送到我的欢迎页面。它完美地工作。问题是某些消息的标题为空,因为它们只是其他消息的答案。我想用我保存到数据库中的 parent_id_msg 标题来更改这个空标题。

但是由于异步代码,我收到了 Promise 对象,但我无法将它用于我的同步代码(导致最后未定义的标题)。在阅读了许多资源并尝试了过去 3 天的一些解决方案之后,我想我理解了与同步代码一起使用的 async/await 的问题,但我仍然不明白如何覆盖它并取得进展。

PS:我不确定我的“异步列表”,但我不知道将异步放在哪里:(

    exports.lastsMessages = (req, res, next) => {
    //find 10 last messages (responses includes)
    let answer = {
        count : 0,
        list:[]
    };
    let tmp;
    Message.findAndCountAll({
        order:[['creation_date', 'DESC']],
        offset: 10 * req.body.pageNbr - 10,
        limit: 10
    })
        .then( async list=>{
                answer.count = list.count;
                for(let i = 0; i<list.rows.length;i++){
                    tmp = list.rows[i].dataValues;
                    if(tmp.title === null || tmp.title === ""){
                        console.log('before'+ tmp.title) // output NULL as expected
                        tmp.title =   await findTitle(tmp.parent_msg_id);
                        console.log('after '+ tmp.title)// output undefined, not as expected :(
                    }
                    answer.list.push(tmp)
                };
            res.status(200).json({...answer, message:'10 derniers messages'})
        })
        .catch(error => res.status(400).json({error, message:'Messages non récupérés'}));     
  };
  async function findTitle(parentId){
    Message.findOne(
        {attributes:['title'], 
        where:{id:parentId}})
        .then(potatoes=> {
            console.log('inside '+ potatoes.dataValues.title)
            //output parent message title inside function, as excepted
            return potatoes.dataValues.title});
 };

提前感谢您(对于潜在的错误、误解和英语水平,作为初学者,我们深表歉意)

【问题讨论】:

    标签: node.js asynchronous async-await


    【解决方案1】:

    你没有从 findTitle 返回任何东西。

    在 findTitle 函数的第一行试试这个:

    return Message.findOne(...
    

    findTitle 函数也不需要是异步的,因为您没有在其中使用 await。另外,在循环中使用 await 通常是个坏主意。

    【讨论】:

    • 首先,Alex,感谢您的快速回答,这很有帮助。如果我删除异步,那么我必须删除上面所有的等待和异步。如果我这样做并返回 Message.findOne(),我不会再收到 undefine 而是一个空对象。我认为 findOne 是 sequelize 的异步方法,所以我保持异步并等待,我终于在我的显示中得到了很好的结果
    • 但是使用这个解决方案,我必须“等待”进入一个循环,如果你说这是一个坏主意,我相信你。如何改进代码?
    • 当我说“findTitle 不需要异步”时,我只是说该函数不需要定义为异步,因为您没有在其中使用 await。例如,这个:“async function findTitle(parentId){”可以更改为:“function findTitle(parentId){”至于循环内的异步问题,解决方案取决于您要实现的目标以及您的数据库结构。最简洁的方法是向父文档添加一个引用,然后您可以填充它,而不是执行两个查询。 mongoosejs.com/docs/populate.html
    • 我建议向消息模型添加一个 ref 属性(在某些情况下可能不需要,但这很好),然后您可以填充它。填充后,您可以调用 message.parent.dataValues.title 来获取父文档的标题。这意味着您不必执行另一个查询来获取父标题,因为它已经填充在“父”属性下的现有消息中。
    • 抱歉,刚刚看到您使用的是 Sequelize。这是他们关于外键和人口的文档的链接:sequelize.org/v3/docs/associations
    猜你喜欢
    • 1970-01-01
    • 2016-12-05
    • 2018-08-28
    • 1970-01-01
    • 1970-01-01
    • 2020-04-08
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多