javascript - .map 函数内的异步验证

标签 javascript node.js postgresql sequelize.js

我正在使用 Node JS、Sequelize 和 Postgres 数据库开发应用程序的后端。
注册类(class)时,用户必须告知将链接到哪些组织、公司和教师。
组织 ID 通过数组传递到后端,我正在尝试进行检查以确保传递的 ID 存在。
到目前为止我所做的是:

const { organizations } = req.body;
const organizationsArray = organizations.map(async (organization) => {
  const organizationExists = await Organization.findByPk(organization);
  if (!organizationExists) {
    return res
      .status(400)
      .json({ error: `Organization ${organization} does not exists!` });
  }
  return {
    course_id: id,
    organization_id: organization,
  };
});
await CoursesOrganizations.bulkCreate(organizationsArray);
这个link有完整的 Controller 代码,相信会方便理解。
当 !OrganizationExists 为真时,我得到该组织不存在的返回。问题是当组织存在时,我得到以下 message error

最佳答案

Array.map() 返回一个 promise 数组,您可以使用 Promise.all() 将其解析为一个数组。在 map 内,您应该使用 throw new Error() 来突破 map - Promise.all() 会引发此错误,然后您可以捕获它并将错误返回给客户端(或吞下它等)。
这是您模式的更正版本,解决了 Promise 结果。

const { organizations } = req.body;
try {
  // use Promise.all to resolve the promises returned by the async callback function
  const organizationsArray = await Promise.all(
    // this will return an array of promises
    organizations.map(async (organization) => {
      const organizationExists = await Organization.findByPk(organization, { 
        attributes: ['id'], // we only need the ID
        raw: true, // don't need Instances
      });
      if (!organizationExists) {
        // don't send response inside the map, throw an Error to break out
        throw new Error(`Organization ${organization} does not exists!`);
      }
      // it does exist so return/resolve the value for the promise
      return {
        course_id: id,
        organization_id: organization,
      };
    })
  );

  // if we get here there were no errors, create the records
  await CoursesOrganizations.bulkCreate(organizationsArray);

  // return a success to the client
  return res.json({ success: true });
} catch (err) {
  // there was an error, return it to the client
  return res.status(400).json({ error: err.message }); 
}
这是一个重构版本,通过在一个查询中获取所有 Organizations 然后进行检查/创建 Course 插入,速度会快一些。
const { Op } = Sequelize;
const { organizations } = req.body;
try {
  // get all Organization matches for the IDs
  const organizationsArray = await Organization.findAll({
    attributes: ['id'], // we only need the ID
    where: {
      id: {
        [Op.in]: organizations, // WHERE id IN (organizations) 
      }
    },
    raw: true, // no need to create Instances
  });

  // create an array of the IDs we found
  const foundIds = organizationsArray.map((org) => org.id);

  // check to see if any of the IDs are missing from the results
  if (foundIds.length !== organizations.length) {
    // Use Array.reduce() to figure out which IDs are missing from the results
    const missingIds = organizations.reduce((missingIds, orgId) => {
      if (!foundIds.includes(orgId)){
        missingIds.push(orgId);
      }
      return missingIds;
    }, []); // initialized to empty array

    throw new Error(`Unable to find Organization for: ${missingIds.join(', ')}`);
  }

  // now create an array of courses to create using the foundIds
  const courses = foundIds.map((orgId) => {
    return {
      course_id: id,
      organization_id: orgId,
    }; 
  });

  // if we get here there were no errors, create the records
  await CoursesOrganizations.bulkCreate(courses);

  // return a success to the client
  return res.json({ success: true });
} catch (err) {
  // there was an error, return it to the client
  return res.status(400).json({ error: err.message }); 
}

关于javascript - .map 函数内的异步验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64390713/

相关文章:

javascript - 我如何检查对象的 typeSoftware 是否具有 (-1) 值并将其从中删除?

javascript - 将数据传递给客户端 JavaScript(最好没有 View 引擎或 cookie)

javascript - 加载 Express-routed Partial 后触发 AngularJS

postgresql - 保留多个 PostgreSQL 基础备份是否有值(value)?

Javascript 不适用于 FireFox for Android,仅适用于我的网站

JavaScript "Undefined is not a function"循环访问对象数组时

node.js - Nodejs + Express - 无法调用未定义的方法 'json'

sql - 按顺序对所有行进行编号

使用连接和条件聚合的 SQL 更新

javascript - ng-repeat中的AngularJS多个倒计时