【问题标题】:How to loop around asynchronous functions in nodejs?如何在nodejs中循环异步函数?
【发布时间】:2020-04-22 17:39:57
【问题描述】:

我正在尝试使用 ID 从数据库中获取帖子。所以我正在循环一个 ID 数组并使用 mongoose 方法“findById”来获取响应。但是循环在完成正文之前完成了迭代。 如何处理?


function getSortedPosts(callback){
    var landingPosts = new Object;
    categoryModel.find((err,categories) => {
        if(err) console.log(err);
        else{
            categories.forEach((category,i) => {
                landingPosts[category.category] = new Array;
                //for each post in  a category
                category.posts.forEach((postid,j) => {
                    console.log(":")
                    //limiting posts per category to 3
                    if (j<3){
                        postModel.findById(postid,(err,foundpost) => {
                            if(err) console.log(err)
                            else{
                                landingPosts[category.category].push(foundpost);
                                if(i === categories.length-1){
                                    console.log(i)
                                    if(j === 2){
                                      callback(landingPosts);
                                    }
                                }
                            }
                        })
                    }
                })
            })
        }
    })
}
getSortedPosts((lp) => {.......})

我不知道如何使用 Promise 或异步等待...所以我使用回调。 现在学习它们会帮助我吗? (由于我是初学者,我打算在当前项目之后学习它们,它们让我感到困惑)

【问题讨论】:

  • “现在学习它们对我有帮助吗?” 是的,但是你需要 findById 的包装器,而 seem to return a promise 不需要(我发现真奇怪,我以为他们在 API 中添加了 Promise)。
  • 是否:A) 重要的是,操作以 series 运行(一个接一个); B) 重要的是它们并行运行(一次全部,重叠);或 C) 无论哪种方式都可以?
  • My answer here 展示了如何执行多个异步操作(有和没有承诺),但我犹豫是否将这个问题作为那个问题的副本来重复......虽然我认为它确实是由SO的定义。
  • 我希望它们串联运行。 A)。
  • 关于var landingPosts = new Object;的旁注:几乎没有任何理由使用new Object代替{},就像这样:var landingPosts = {};

标签: javascript node.js asynchronous mongoose


【解决方案1】:

在开始这个项目之前,你绝对应该学习async await

async function getSortedPosts() {
    var landingPosts = {};
    var categories = await categoryModel.find().catch(console.log);
    for(let item of categories) {
        let category = item.category;
        landingPosts[category] = [];

        for(let id of item.posts.slice(0,2)) {
            let post = await postModel.findById(id).catch(console.log);
            landingPosts[category].push(post);
        }
    }

    return landingPosts;
}

像这样调用getSortedPosts函数 -

getSortedPosts().then(landingPosts => {
    // some logic
})

我没有运行代码,但希望你能解决错误。

【讨论】:

    【解决方案2】:

    我会将功能划分为不同的功能,这些功能只做一项工作,然后让另一个使用这些功能来获得最终输出。像这样的

    function findPostById(postId) {
      return new Promise((resolve, reject) => {
        postModel.findById(postid, (err, foundpost) => {
          if (err) {
            reject(err);
          } else {
            resolve(foundpost);
          }
        });
      });
    }
    
    function findCategories() {
      return new Promise((resolve, reject) => {
        categoryModel.find((err, categories) => {
          if (err) {
            reject(err);
          }
          resolve(categories);
        });
      });
    }
    
    async function getSortedPosts() {
      const categories = await findCategories();
      const landingPosts = {};
      for (const category of categories) {
        for (const post of category.posts) {
          const foundpost = await findById(post.postId);
          landingPosts[category.category].push(foundpost);
        }
      }
    }
    
    

    我还没有完成限制帖子数量的逻辑,但你知道如何构建代码。

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 2019-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-26
      • 1970-01-01
      • 2020-03-07
      相关资源
      最近更新 更多