@amenov
Full-stack developer

Как использовать Promise в цикле?

Всем привет!

Пишу свой валидатор входных данных на JavaScript, проблема в том что там внутри все на циклах, проверках и тд. Так в целом все работает. Но когда я внутри циклов пытаюсь проверить в БД на уникальность какое то значение он не дожидается результата и делает вид что ошибки нет и создает в БД пользователя. Я не гуру я учусь, буду признателен за ответ. Подскажите чтобы логика осталось примерно такой же. Спасибо!

Вот пример кода:

const request = {
name: "Абдулсалам",
age: 21,
email: "abdulsalam@domain.zone"
}

const rules = {
name: "required|string",
age: "required|number|min:18",
email: "required|email|unique:users"
}

const Validator = require("../Classes/Validator");

const validator = new Validator(request, rules);

if (validator.fails()) {
  const response = {
    message: "Bad Request",
    success: false,
    status: 400,
    data: { errors: validator.errors },
  };

  return res.status(response.status).json(response);
}


Код валидатора:

const { QueryTypes } = require("sequelize");
const { sequelize } = require("../../models/index");

class Validator {
  constructor(request, rules) {
    this.request = request;
    this.rawRules = rules;
  }

  errors = [];
  currentKey = null;

  set addError(message) {
    this.errors.push({ [this.currentKey]: message });
  }

  get rules() {
    const rules = [];

    for (const key in this.rawRules) {
      rules.push({ [key]: this.rawRules[key].split("|") });
    }

    return rules;
  }

  fails() {
    this.rules.forEach((objRules) => {
      for (const key in objRules) {
        const rules = objRules[key];
        const request = this.request[key];

        this.currentKey = key;

        // EXISTS
        if (rules.includes("exists") && !request) return;

        // REQUIRED
        if (
          rules.includes("required") &&
          (request === "" || request === null || request === undefined)
        )
          return (this.addError = "Required field");

        // STRING
        if (rules.includes("string") && typeof request !== "string")
          return (this.addError = "This field must be a string");

        // NUMBER
        if (rules.includes("number") && typeof request !== "number")
          return (this.addError = "This field must be a number");

        // EMAIL
        if (
          rules.includes("email") &&
          !request.match(
            /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i
          )
        )
          return (this.addError = "Invalid email");

        // ":"
        rules.forEach(async (rule) => {
          if (rule.includes(":")) {
            const [ruleKey, ruleValue] = rule.split(":");

            const findRuleKey = (key) => ruleKey.includes(key);

            // "-"
            if (ruleValue.includes("-")) {
              const [ruleValueLeft, ruleValueRight] = ruleValue.split("-");

              // BETWEEN MIN-MAX
              if (findRuleKey("between")) {
                // BETWEEN MIN
                if (
                  !(
                    (typeof request === "string" ? request.length : request) >=
                    ruleValueLeft
                  )
                )
                  return (this.addError = `Minimum ${
                    typeof request === "string" ? "length" : "number"
                  }: ${ruleValueLeft}`);

                // BETWEEN MAX
                if (
                  !(
                    (typeof request === "string" ? request.length : request) <=
                    ruleValueRight
                  )
                )
                  return (this.addError = `Maximum ${
                    typeof request === "string" ? "length" : "number"
                  }: ${ruleValueRight}`);
              }
            }

            // MIN
            if (
              findRuleKey("min") &&
              !(
                (typeof request === "string" ? request.length : request) >=
                ruleValue
              )
            )
              return (this.addError = `Minimum ${
                typeof request === "string" ? "length" : "number"
              }: ${ruleValue}`);

            // MAX
            if (
              findRuleKey("max") &&
              !(
                (typeof request === "string" ? request.length : request) <=
                ruleValue
              )
            )
              return (this.addError = `Maximum ${
                typeof request === "string" ? "length" : "number"
              }: ${ruleValue}`);

            // AS
            if (findRuleKey("as") && request !== this.request[ruleValue])
              return (this.addError = `The value of the field "${this.currentKey}" does not match the value of the field "${ruleValue}"`);

            // NOT
            if (
              findRuleKey("not") && typeof request === "string"
                ? request.toLowerCase() === ruleValue
                : request === +ruleValue
            )
              return (this.addError = `Field "${this.currentKey}" cannot contain the value "${ruleValue}"`);

            // LENGTH
            if (
              findRuleKey("length") &&
              typeof request === "string" &&
              request.length !== +ruleValue
            )
              return (this.addError = `The string length should be: ${ruleValue}`);

            // UNIQUE
            if (findRuleKey("unique")) {
              const result = await sequelize.query(
                `SELECT * FROM ${ruleValue} WHERE ${this.currentKey} = "${request}"`,
                { type: QueryTypes.SELECT }
              );

              if (!!result[0])
                return (this.addError = `SELECT * FROM ${ruleValue} WHERE ${this.currentKey} = "${request}"`);
            }
          }
        });
      }
    });

    return !!this.errors.length;
  }
}

module.exports = Validator;
  • Вопрос задан
  • 1671 просмотр
Решения вопроса 2
Tim-A-2020
@Tim-A-2020
Использовать конструкцию
for await (variable of iterable) {
  
}

https://developer.mozilla.org/ru/docs/Web/JavaScri...
или сделать через Promise.allSettled()
https://developer.mozilla.org/ru/docs/Web/JavaScri...
Ответ написан
Комментировать
wapster92
@wapster92 Куратор тега JavaScript
async/await, for await, https://habr.com/ru/post/435084/
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы