【问题标题】:javascript promise after foreach loop with multiple mongoose find带有多个猫鼬查找的foreach循环后的javascript承诺
【发布时间】:2019-05-22 14:59:04
【问题描述】:

我正在尝试使用一些 db 调用进行循环,一旦它们全部完成,就会发送结果。 - 使用一个承诺,但如果我在回调之后有我的承诺,它就不起作用。

  let notuser = [];


  let promise = new Promise((resolve, reject) => {

  users.forEach((x) => {


    User.find({
      /* query here */
    }, function(err, results) {
        if(err) throw err

    if(results.length) {
          notuser.push(x);
          /* resolve(notuser)  works here - but were not done yet*/ 
        }
    })
  });

  resolve(notuser); /*not giving me the array */

}).then((notuser) => {

return res.json(notuser)

})

我该如何处理?

【问题讨论】:

  • 映射查询承诺数组并使用Promise.all()

标签: javascript node.js mongoose promise


【解决方案1】:

下面是一个名为findManyUsers 的函数,它可以满足您的需求。 Mongo find 会返回一个 Promise 给你,所以只需在循环中收集这些 Promise 并与 Promise.all() 一起运行它们。所以你可以看到它的实际效果,我添加了一个模拟 User 类,它带有一个返回 promise 的 find 方法......

// User class pretends to be the mongo user. The find() method
// returns a promise to 'find" a user with a given id
class User {
    static find(id) {
        return new Promise(r => {
            setTimeout(() => r({ id: `user-${id}` }), 500);
        });
    }
}

//  return a promise to find all of the users with the given ids
async function findManyUsers(ids) {
    let promises = ids.map(id => User.find(id));
    return Promise.all(promises);
}

findManyUsers(['A', 'B', 'C']).then(result => console.log(result));

【讨论】:

    【解决方案2】:

    我建议你看看async,它是一个很棒的库,可以处理这类事情等等,我真的认为你应该习惯于实现它。

    我会使用以下方法解决您的问题

    const async = require('async')
    
    let notuser = [];
    
    async.forEach(users, (user, callback)=>{
         User.find({}, (err, results) => {
              if (err) callback(err)
    
              if(results.length) {
                   notUser.push(x)
                   callback(null)
              }
         })
    }, (err) => {
         err ? throw err : return(notuser)
    })
    

    但是,如果您不想使用 3rd 方库,最好使用 promise.all 并等待它完成。

    编辑:记得安装async 使用npmyarn 类似于yarn add async 的东西——npm install async

    【讨论】:

    • err ? throw err : return(notuser) 在异步回调中真的没有意义
    • 我只是按照他的逻辑,他想在有错误的时候抛出一个错误。我的示例背后的目标是向用户展示 async
    【解决方案3】:

    我使用@danh 解决方案作为在我的场景中进行修复的基础(因此值得称赞),但我认为我的代码可能与其他人相关,希望在没有异步的情况下使用标准猫鼬。我想获取某个状态的报告数量的摘要,并返回每个报告的最后 5 个,并合并为一个响应。

    const { Report } = require('../../models/report');
    const Workspace = require('../../models/workspace');
    
    // GET request to return page of items from users report
    module.exports = (req, res, next) => {
      const workspaceId = req.params.workspaceId || req.workspaceId;
      let summary = [];
    
      // returns a mongoose like promise
      function addStatusSummary(status) {
        let totalItems;
        let $regex = `^${status}$`;
        let query = {
          $and: [{ workspace: workspaceId }, { status: { $regex, $options: 'i' } }],
        };
    
        return Report.find(query)
          .countDocuments()
          .then((numberOfItems) => {
            totalItems = numberOfItems;
            return Report.find(query)
              .sort({ updatedAt: -1 })
              .skip(0)
              .limit(5);
          })
          .then((reports) => {
            const items = reports.map((r) => r.displayForMember());
            summary.push({
              status,
              items,
              totalItems,
            });
          })
          .catch((err) => {
            if (!err.statusCode) {
              err.statusCode = 500;
            }
            next(err);
          });
      }
    
      Workspace.findById(workspaceId)
        .then((workspace) => {
          let promises = workspace.custom.statusList.map((status) =>
            addStatusSummary(status)
          );
          return Promise.all(promises);
        })
        .then(() => {
          res.status(200).json({
            summary,
          });
        })
        .catch((err) => {
          if (!err.statusCode) {
            err.statusCode = 500;
          }
          next(err);
        });
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-04
      • 2015-03-05
      • 2016-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多