同步流输出

时间:2019-02-15 14:29:13

标签: node.js express stream synchronization aws-sdk

我正在将不同大小的图像上传到Amazon s3存储。每当我上传图像时,我都会创建图像的三个独立的可读流,并将其通过管道传递给我的缩放器功能和s3上传功能。

每个流都将不同大小的图像上载到s3云。我希望同步流的输出,以便在三个流中的所有流都完成上传后可以发送上传的照片的URL。

我无法知道我所有的流何时结束。还是要等到所有流都结束后再返回所有上传图像的URL?

这是我的代码

resize.js

import fs from 'fs';
import sharp from 'sharp';

export const resizeThumbnail = function (path, format) {
  const readStream = fs.createReadStream(path);
  let transform = sharp();
  if (format) {
    transform = transform.toFormat(format);
  }
  transform = transform.resize(100);
  return readStream.pipe(transform);
};

export const resizeLowRes = function (path, format) {
  const readStream = fs.createReadStream(path);
  let transform = sharp();
  if (format) {
    transform = transform.toFormat(format);
  }
  transform = transform.resize(500);
  return readStream.pipe(transform);
};

export const resizeHighRes = function (path, format) {
  const readStream = fs.createReadStream(path);
  let transform = sharp();
  if (format) {
    transform = transform.toFormat(format);
  }
  transform = transform.resize(1080);
  return readStream.pipe(transform);
};

resizer.js

import { resizeThumbnail, resizeLowRes, resizeHighRes } from './resize';
import awsConfig from '../config/awsConfig';
import { uploadFromStream } from './amazonS3';

// receives a list of images
export const resizer = (images, id, callback) => {
  const imageList = images.split(',');
  const store = [];
  imageList.forEach((imagePath, i) => {
    sizeCreator(imagePath, id, i, (err, localstore) => {
      if (!err) {
        store.push(localstore);
        console.log(store);
      }
      callback(err);
    });
  });
};

const sizeCreator = (imagePath, id, i, callback) => {
  const localstore = {};
  resizeThumbnail(imagePath).pipe(uploadFromStream(awsConfig, id, i, 'thumbnail', (err, data) => {
    localstore.thumbnail = {
      url: data.Location,
      filename: data.key,
    };
  }));
  resizeLowRes(imagePath).pipe(uploadFromStream(awsConfig, id, i, 'lowres', (err, data) => {
    localstore.lowres = {
      url: data.Location,
      filename: data.key,
    };
  }));
  resizeHighRes(imagePath).pipe(uploadFromStream(awsConfig, id, i, 'highres', (err, data) => {
    localstore.highres = {
      url: data.Location,
      filename: data.key,
    };
    callback(err, localstore);
  }));
};

amazonS3.js

import stream from 'stream';

export const uploadFromStream = (s3, id, index, res, callback) => {
  const pass = new stream.PassThrough();
  const params = {
    Bucket: 'Bucket',
    Key: `${id}_${res}_${index}`,
    Body: pass,
    ContentType: 'image/jpeg',
  };
  s3.upload(params, (err, data) => {
    callback(err, data);
  });
  return pass;
};

1 个答案:

答案 0 :(得分:0)

您可以对开始的流进行计数,并在完成流事件时更新计数器。当最后一个流完成时,计数器的值应为0。然后您可以触发发送URL的不同事件。