为了账号安全,请及时绑定邮箱和手机立即绑定

.map 函数中的异步验证

.map 函数中的异步验证

回首忆惘然 2023-05-18 10:49:17
我正在使用 Node JS、Sequelize 和 Postgres 数据库开发应用程序的后端。注册课程时,用户必须告知哪些组织、公司和教师将与其相关联。组织 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);
查看完整描述

2 回答

?
牧羊人nacy

TA贡献1862条经验 获得超7个赞

正在Array.map()返回一个承诺数组,您可以使用Promise.all(). 在地图内部,您应该使用throw new Error()break out of 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 }); 

}


查看完整回答
反对 回复 2023-05-18
?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

如果你有一个 ID 数组并且你想检查它们是否存在你应该使用 (in) 运算符,这使得你只访问数据库一次并一次获取所有记录(而不是获取它们一个一个循环),在你得到这些记录后,你可以检查它们的长度以确定它们是否都存在。


const { Op } = require("sequelize");

let foundOrgs = await Organization.findAll({

  where: {

    id: {

      [Op.in]: organizationsArray,

    }

  }

});


查看完整回答
反对 回复 2023-05-18
  • 2 回答
  • 0 关注
  • 139 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信