【问题标题】:Images are not getting downloaded using promises [duplicate]没有使用承诺下载图像[重复]
【发布时间】:2020-10-22 00:17:29
【问题描述】:

我需要下载所有图片并使用它们生成 word 文档。 使用 nodeJS 和 Meteor

WebApp.connectHandlers.use('/download', async function (req, res, next) {
  // ...

  const images = [];

  await lines.forEach(async (line, k) => {
    if (line.type && line.type === 'image') {
      images.push({
        id: line.id,
        file: line.id + '.jpg',
      });

      download_image(line.imageUrl, line.id + '.jpg');
    }
  });

  // ...

  // Then I use images[] to insert them into a Word document.
});

const download_image = (url, image_path) =>
  axios({
    url,
    responseType: 'stream',
  }).then(
    (response) =>
      new Promise((resolve, reject) => {
        response.data
          .pipe(fs.createWriteStream(image_path))
          .on('finish', () => resolve())
          .on('error', (e) => reject(e));
      })
  );

问题是在我将图像插入 Word 文档之前没有下载图像。

如何在图像下载完成之前停止/等待?我不太擅长承诺。她缺什么?

谢谢!

【问题讨论】:

标签: javascript node.js promise async-await es6-promise


【解决方案1】:

使用带有async 函数的.forEach(或类似的数组方法)的常见错误。 async function 只是意味着它返回承诺,await 的工作方式与将承诺与then 链接在一起的方式相同。因此,wait lines.forEach(async (line, k) => { 这一行只会创建并返回一堆 Promise,但它不会等待里面的所有 Promise 完成。

WebApp.connectHandlers.use('/download', async function (req, res, next) {
  // ...

  const images = [];
  const promises = [];
  lines.forEach((line, k) => {
    if (line.type && line.type === 'image') {
      images.push({
        id: line.id,
        file: line.id + '.jpg',
      });

      promises.push(download_image(line.imageUrl, line.id + '.jpg'));
    }
  });
  // here you get array with all the images downloaded
  const downloadedImages = await Promise.all(promises);
  // this line will be executed after you download all images

  // ...
});

// This function would work same with or without the `async` keyword 
// (because async function return promise - you are returning the promise. 
// Async function allows to use await, but you are not using await in this function).
// However it is good practice to have all functions that returns promise 
// marked as `async` so you know that you receive promise from it.
const download_image = async (url, image_path) =>
  // Dont forget to return your promise otherwise you cannot await it
  return axios({
    url,
    responseType: 'stream',
  }).then(
    (response) =>
      new Promise((resolve, reject) => {
        response.data
          .pipe(fs.createWriteStream(image_path))
          .on('finish', () => resolve())
          .on('error', (e) => reject(e));
      })
  );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-16
    • 1970-01-01
    • 2015-11-19
    • 1970-01-01
    • 2016-04-10
    • 2014-12-18
    • 2015-08-06
    • 2015-11-26
    相关资源
    最近更新 更多