Не удается правильно использовать array.every() и получить неправильный результат

#javascript #express #nestjs #typeorm #class-validator

#javascript #выразить #nestjs #typeorm #класс-валидатор

Вопрос:

Я пытаюсь проверить массив идентификаторов, для проверки я использую пользовательский валидатор в проекте nestjs. Я передаю массив идентификаторов в функции обратного вызова своему классу обслуживания для запроса из базы данных, существует ли идентификатор в таблице или нет, и возвращает логическое значение. Каждый раз, когда я получаю логическое значение true, даже если я передаю неправильный идентификатор.

Вот функция проверки в пользовательском валидаторе

 import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments, registerDecorator, ValidationOptions } from "class-validator";
import { DeviceService } from "../device/device.service";
import { Injectable } from "@nestjs/common";


@ValidatorConstraint({ async: true })
@Injectable()
export class DevicesArrayValidatorConstraint implements ValidatorConstraintInterface {

    constructor(private deviceService: DeviceService) { }

    async validate(devices: Array<number>, args: ValidationArguments) {
        let result = devices.every(async (deviceId) => await this.deviceService.validateDevice(deviceId));
        if(result){
            return true;
        }
        else{
            return false;
        }
    }

    defaultMessage(args: ValidationArguments) { // here you can provide default error message if validation failed
        return "Here is an error";
    }

}

export function ValidDevices(validationOptions?: ValidationOptions) {
    return function (object: Object, propertyName: string) {
        registerDecorator({
            target: object.constructor,
            propertyName: propertyName,
            options: validationOptions,
            validator: DevicesArrayValidatorConstraint
        });
    };
}
  

Это функция из класса обслуживания

 async validateDevice(deviceId: number) {
  try {
    let result = await this.deviceRepository.findOneOrFail(deviceId)
    if(result){
      console.log(`In try block,This is id ${  deviceId}`)
    }
  } catch (error) {
    return false;
  }
  return true;
}
  

Если я передаю массив devices: [1,4] , где 1 является допустимым, а 4 недопустимым. Я получаю двойной логический результат, если я console.log() возвращаю значение.

прикрепление сообщения консоли введите описание изображения здесь

Комментарии:

1. every не понимает асинхронные функции. Он просто видит обещание, которое возвращается как истинное значение.

2. что может быть обходным путем?

3. if(result) { return true; } else { return false; } result уже является логическим значением, поэтому вы можете просто return result

4. Тоже так делал, но всегда получал логическое значение true;

Ответ №1:

every не понимает асинхронные функции. Он просто видит обещание, которое возвращается как истинное значение.

У вас есть несколько вариантов:

Если вы хотите проверить все устройства параллельно, проверьте результат:

 const validityFlags = await Promise.all(devices.map(deviceId => this.deviceService.validateDevice(deviceId)));
let result = validityFlags.every(Boolean);
  

Или, если вы хотите проверять каждое устройство последовательно, не беспокоясь о более поздних, если вы знаете, что более раннее недопустимо:

 let result = true;
for (const deviceId of devices) {
    const valid = await this.deviceService.validateDevice(deviceId);
    if (!valid) {
        result = false;
        break;
    }
}
  

Комментарии:

1. (Дох! Опечатка. Если вы видите for-in цикл выше, нажмите обновить. Это должен быть for-of цикл.)

2. @Andreas — ЛОЛ, довольно. Итак, две опечатки. 🙂 Спасибо!!

3. Та же проблема, если я проверяю все устройства параллельно.

4. и если я проверяю каждое устройство, я не могу использовать break, потому что мне нужно логическое значение, которое break не позволяет передавать;

5. @Hareemrehan Вы можете заменить тело своей async validate(...) { ... } функции одной из двух версий из этого ответа, и она должна работать. «Я не могу использовать break, потому что мне нужно логическое значение» — отсюда result и переменная.