【并发的应用】

69 阅读2分钟

需求1:

当提交文章的时候,校验图文横图是否超过限制,如果超过就不能提交这篇文章

不使用并发的代码实现:

// 辅助函数,检查图片的方向
const checkImageOrientation = (imgUrl: string): Promise<boolean> => {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => {
      // 判断是否是横图
      resolve(img.width > img.height);
    };
    img.onerror = () => {
      // 图片加载失败时返回  true
      reject(true);
    };
    img.src = imgUrl;
  });
};

export const checkLandscapeCount = async (
  imgs: string[], // 图片地址数组
  maxLandscapeCount: number, // 最大横图数量
  onSuccess?: () => void, // 校验成功时的回调
  onFail?: (imageUrls: string[]) => void // 校验失败时的回调
) => {
  console.log("maxLandscapeCount", maxLandscapeCount);
  if (maxLandscapeCount && imgs && imgs.length > 0) {
    // 如果有  imgs 里面 有 maxLandscapeCount 个, 	Modal.warn, 同事 return false
    let landscapeCount = 0;

    let landscapeImages: string[] = []; // 用于存储横图的图片链接

    // 遍历所有图片,逐个加载
    for (let imgUrl of imgs) {
      const isLandscape = await checkImageOrientation(imgUrl);
      console.log("isLandscape", isLandscape);
      if (isLandscape) {
        landscapeCount++;
        landscapeImages.push(imgUrl); // 保存横图的图片链接
      }
      // 如果横图数量超过限制,弹出提示并返回 false
      if (landscapeCount > maxLandscapeCount) {
        onFail?.(landscapeImages);
        return false;
      }
    }
  }
  onSuccess?.();
  return true;
};

使用并发代码实现:

const checkLandscapeCount = async (
  imgs: string[], // 图片地址数组
  maxLandscapeCount: number, // 最大横图数量
  onSuccess?: () => void, // 校验成功时的回调
  onFail?: (imageUrls: string[]) => void // 校验失败时的回调
) => {
  if (!imgs || imgs.length === 0) {
    return true; // 如果没有图片,直接返回成功
  }

  let landscapeCount = 0;
  let landscapeImages: string[] = []; // 用于存储横图的图片链接

  // 使用并发控制的方式加载图片并检查横竖图
  const results = await loadImagesInBatches(imgs);

  // 遍历结果判断横竖图
  for (const [index, isLandscape] of results.entries()) {
    if (isLandscape) {
      landscapeCount++;
      landscapeImages.push(imgs[index]); // 保存横图的图片链接
    }

    // 如果横图数量超出限制,弹出提示并返回 false
    if (landscapeCount > maxLandscapeCount) {
      onFail && onFail(landscapeImages); // 校验失败回调
      return false; // 横图数量超限,返回 false
    }
  }

  // 校验通过,触发 onSuccess 回调
  onSuccess && onSuccess();
  return true; // 校验通过
};

// 辅助函数:加载图片并检查横竖图
const loadImagesInBatches = (
  imgs: string[],
  batchSize = 5
): Promise<boolean[]> => {
  let index = 0;
  const results: Promise<boolean>[] = [];

  // 分批加载图片
  const loadBatch = () => {
    const batch = imgs.slice(index, index + batchSize);
    const batchPromises = batch.map((imgUrl) => checkImageOrientation(imgUrl));
    results.push(...batchPromises);

    // 更新下一个批次的起始索引
    index += batchSize;

    // 如果还有未加载的图片,继续加载下一个批次
    if (index < imgs.length) {
      loadBatch();
    }
  };

  loadBatch();

  // 返回所有批次的结果
  return Promise.all(results);
};

// 辅助函数:检查图片的方向
const checkImageOrientation = (imgUrl: string): Promise<boolean> => {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => {
      // 判断是否是横图
      resolve(img.width > img.height);
    };
    img.onerror = () => {
      // 图片加载失败时返回 false
      reject(false);
    };
    img.src = imgUrl;
  });
};