【问题标题】:Not able to use array.every() correctly and getting wrong result无法正确使用 array.every() 并得到错误的结果
【发布时间】:2021-01-25 10:30:42
【问题描述】:

我正在尝试验证一组 Id,为了验证我在 nestjs 项目中使用自定义验证器。我将回调函数中的 id 数组传递给我的服务类,以从数据库中查询 id 是否存在于表中并返回一个布尔值。每次我收到 boolean true 即使我传递了错误的 id。

这是自定义验证器中的验证函数

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() 返回值,我会得到一个双布尔结果。

附加控制台消息

【问题讨论】:

  • every 不理解异步函数。它只是将返回的承诺视为真实值。
  • 有什么办法解决?
  • if(result) { return true; } else { return false; } - result 已经是一个布尔值,所以你可以简单地 return result
  • 也这样做了,但总是收到 boolean true;

标签: javascript express nestjs typeorm class-validator


【解决方案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;
    }
}

【讨论】:

  • (Doh!错字。如果您在上方看到for-in 循环,请点击刷新。它应该是for-of 循环。)
  • @Andreas - 哈哈,很好。那么两个错别字。 :-) 谢谢!!
  • 如果我并行验证所有设备,也会出现同样的问题。
  • 如果我验证每个设备我不能使用中断,因为我需要一个布尔值,它不允许通过;
  • @Hareemrehan 您可以使用此答案中的两个版本之一替换 async validate(...) { ... } 函数的主体,它应该可以工作。 “我不能使用 break 因为我需要布尔值” - 因此是 result 变量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-11
  • 1970-01-01
  • 2021-10-11
  • 2011-12-24
  • 1970-01-01
  • 1970-01-01
  • 2015-09-20
相关资源
最近更新 更多