【问题标题】:Creating multiple directories and writing multiple files async创建多个目录并异步写入多个文件
【发布时间】:2020-11-28 05:03:54
【问题描述】:

我需要创建多个目录并异步写入多个文件。到目前为止一切顺利,我的代码按预期工作,但我无法让它返回包含成功或失败值的状态。该函数始终返回“未定义”。我知道这与函数在完成任何操作之前返回值有关,但不知道为什么。

const fs = require('fs');
const jimp = require('jimp');

/**
 * Creates a directory recursively
 * @param {Array} paths array of paths
 * @returns {Array} 200 for success ERROR for fail
 */
const createFolderRecursive = async (paths) => paths.map((path) => {
  fs.mkdir(path, { recursive: true }, (err) => {
    if (err) {
      throw err;
    }
  });
  return 200;
});

/**
 * Makes new directory in folder images/products/{ref}
 *  saves products images and thumbnails
 * @param {Array} images Images array to be saved
 * @param {string} sku the product SKU which is going to be the path /images/products/${sku}
 * @returns {Number} if successfull returns 200 else returns 500
 */
const saveImages = async (images, sku) => {
  createFolderRecursive([
    `${__dirname}/../images/products/${sku}`,
    `${__dirname}/../images/products/thumbnails/${sku}`,
  ]).then((a) => {
    if (a.every(((val) => val === 200))) {
      return Promise.all(images.map((image, i) => {
        const base64Image = image.split(';base64,').pop();
        fs.writeFile(`${__dirname}/../images/products/${sku}/image${i}.png`,
          base64Image, { encoding: 'base64' }, (err) => {
            if (err) {
              throw err;
            }
            return 200;
          });

        jimp.read(Buffer.from(base64Image, 'base64')).then((img) => {
          img.resize(jimp.AUTO, 415);
          img.quality(50);
          img.write(`${__dirname}/../images/products/thumbnails/${sku}/image${i}.jpeg`);
          return 200;
        });
      })).then((status) => console.log(status));
    }
    return 500;
  }).catch((err) => err);
};

module.exports = saveImages;

代码有效,所有文件都写入成功,但返回“未定义”。对于另一个模块中的条件,我需要它是 200 或 500。

感谢您的努力。

【问题讨论】:

  • fs.mkdir()fs.writeFile() 不返回承诺。这段代码有多个问题需要解决,但主要问题似乎不在于理解回调和承诺之间的区别。
  • 好的,很酷。你能描述一下你会做些什么来实现这个目标吗?我是否应该删除所有Promisse.all 并仅对fs.mkdir()fs.writeFile() 使用回调。并在fs.writeFile 回调中运行 jimp 函数?谢谢
  • 或者可能只将 jimp.read 包装在一个承诺中,因为它返回一个

标签: javascript asynchronous promise fs


【解决方案1】:

不要设计自己的错误代码,只允许promises根据他们的成功自然解决或拒绝。如果你写的是async functions,你应该利用await关键字而不是.then(...)

const fs = require('fs');
const jimp = require('jimp');

const products = `${__dirname}/../images/products`;

const createFolderRecursive = async paths => {
  const dirPromises = paths.map(path => fs.promises.mkdir(path, { recursive: true }));
  await Promise.all(dirPromises);
};

const saveImage = async (image, index) => {
  const pngBuffer = Buffer.from(image.split(';base64,').pop(), 'base64');
  const pngPromise = fs.promises.writeFile(`${products}/${sku}/image${index}.png`, pngBuffer);
  const img = await jimp.read(pngBuffer);
  const jpgPromise = img
    .resize(jimp.AUTO, 415)
    .quality(50)
    .write(`${products}/thumbnails/${sku}/image${index}.jpeg`);

  await Promise.all([pngPromise, jpgPromise]);
};

const saveImages = async (images, sku) => {
  await createFolderRecursive([
    `${products}/${sku}`,
    `${products}/thumbnails/${sku}`
  ]);

  const imgPromises = images.map(saveImage);
  await Promise.all(imgPromises);
};

module.exports = saveImages;

然后你可以通过调用来检查错误:

saveImages(myImages, mySku).then(
  () => { /* success */ },
  reason => { /* error */ }
);

const someAsyncFunction = async () {
  try {
    await saveImages(myImages, mySku);
    /* success */
  } catch (reason) {
    /* error */
  }
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-17
    • 2021-05-25
    • 1970-01-01
    • 2020-11-23
    • 2019-10-14
    • 2020-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多