简体   繁体   English

如何确保fs.createWriteStream在函数继续执行之前完成; 仅保存一部分图像

[英]How to make sure fs.createWriteStream finishes before function continues; only fraction of image being saved

I am making a request to an API to get a path to an image. 我正在向API提出请求,以获取图像的路径。 I want to save this image to my database in a mongoDB collection so that the users don't need to constantly make API requests. 我想将此图像保存到mongoDB集合中的数据库中,以使用户不需要不断发出API请求。

I have something set up where I make a request to the imagePath and with the response, I pipe fs.createWriteStream(). 我在向imagePath发出请求的地方进行了设置,并通过响应将fs.createWriteStream()传递给管道。

Then later on in the code, I use my schema to create a "Character" using this file. 然后,在代码的后面,我使用我的模式使用该文件创建一个“字符”。 It works, but it only saves a fraction of the image, like a top 1/5th. 它可以工作,但只保存图像的一小部分,例如顶部的1/5。 It's not finishing before it continues. 尚未完成,还没有结束。

I tried making the function async and then using await before my url request. 我试着使函数异步,然后在我的URL请求之前使用await。 I have also tried various express/fs methods, like writeFileSync() but those haven't worked. 我也尝试了各种express / fs方法,例如writeFileSync(),但是这些方法没有用。

How do I get the file to finish writing before it does the mongoDB dance? 我如何在mongoDB跳舞之前使文件完成写入?


 let imagePath = req.body.characterObject.thumbnail.path + '.' + req.body.characterObject.thumbnail.extension;

 let superPath = './uploads/marvelousImage.jpg';
let marvelousImage;
  axios({
      url: imagePath,
      responseType: 'stream',
  })
  .then(response => {
      marvelousImage = response.data.pipe(fs.createWriteStream(superPath));

  })
  .catch(err => {
      console.log(err)
  });

    User.findOne({  "username": "administrator"})
    .then(user => {
      let characterId = req.body.characterObject.id;
      for(let i = 0; i < user.characters.length; i++) {
        if(characterId == user.characters[i].id) {
          return Promise.reject({
            code: 422,
            message: 'You already have this character!',
            reason: "CharacterDuplicationError"
          });
        }
      }
      console.log(req.body.characterObject);
      Character.create({
          description: req.body.characterObject.description || 'bocho',
          events: req.body.characterObject.events || 'lopo',
          thumbnail: req.body.characterObject.thumbnail || 'goso',
          name: req.body.characterObject.name || 'John Doe',
          id: req.body.characterObject.id,
          "image.data": fs.readFileSync(superPath),
          "image.contentType": 'image/jpeg'
      })
      .then(char => {
          console.log('lalala');
          console.log(char);
        user.characters.push(char);
        user.save();
        return res.status(201).json({message: "Character Added!"})
      })
    .catch(err => {
        if(err.reason === "CharacterDuplicationError") {
          return res.send(err);
        } 
    })
   })
 });

It isn't clear that this is your only issue here, but it is one of the issues. 目前尚不清楚这是您唯一的问题,但这是问题之一。

In this code: 在此代码中:

  .then(response => {
      marvelousImage = response.data.pipe(fs.createWriteStream(superPath));

  })

The promise chain is not waiting for the pipe to finish reading/writing. Promise链不等待管道完成读/写。 To do that, you need to return a promise from that .then() handler that resolves when the reading/writing is done. 为此,您需要从该.then()处理函数返回一个承诺,该承诺将在完成读/写操作时进行解析。 You can do that by listening to events on the writeStream. 您可以通过侦听writeStream上的事件来实现。 .pipe() returns the write stream so we can use that return value to set up event handlers and then use those events to resolve/reject a promise that we return. .pipe()返回写流,因此我们可以使用该返回值来设置事件处理程序,然后使用这些事件来解析/拒绝我们返回的承诺。 This will make the promise chain wait for the streaming to finish before going to the next .then() in the promise chain. 这将使Promise链等待流完成,然后再转到.then()链中的下一个.then()

 .then(response => {
     return new Promise((resolve, reject) => {
         marvelousImage = response.data.pipe(fs.createWriteStream(superPath));
         marvelousImage.on('error', reject).on('close', resolve);
     });
  });

Then, I immediately see that you start your database stuff outside of the promise chain. 然后,我立即看到您在promise链之外启动数据库。 That has to be inside the promise chain. 那必须在承诺链之内。

I attempted to put everything into the promise chain here and flatten the chain and clean up your error handling: 我试图将所有内容放入此处的诺言链,并拉平链条并清理您的错误处理:

let imagePath = req.body.characterObject.thumbnail.path + '.' + req.body.characterObject.thumbnail.extension;
let superPath = './uploads/marvelousImage.jpg';

axios({
    url: imagePath,
    responseType: 'stream'
}).then(response => {
     return new Promise((resolve, reject) => {
         let marvelousImage = response.data.pipe(fs.createWriteStream(superPath));
         marvelousImage.on('error', reject).on('close', resolve);
     });
}).then(() => {
    return User.findOne({"username": "administrator"});
}).then(user => {
    let characterId = req.body.characterObject.id;
    for (let i = 0; i < user.characters.length; i++) {
        if (characterId == user.characters[i].id) {
            return Promise.reject({
                code: 422,
                message: 'You already have this character!',
                reason: "CharacterDuplicationError"
            });
        }
    }
    console.log(req.body.characterObject);
    return Character.create({
        description: req.body.characterObject.description || 'bocho',
        events: req.body.characterObject.events || 'lopo',
        thumbnail: req.body.characterObject.thumbnail || 'goso',
        name: req.body.characterObject.name || 'John Doe',
        id: req.body.characterObject.id,
        "image.data": fs.readFileSync(superPath),
        "image.contentType": 'image/jpeg'
    });
}).then(char => {
    console.log('lalala');
    console.log(char);
    user.characters.push(char);
    user.save();
    return res.status(201).json({
        message: "Character Added!"
    })
}).catch(err => {
    console.log(err);
    if (err.reason === "CharacterDuplicationError") {
        res.send(err);
    } else {
        res.sendStatus(500);
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 未捕获的TypeError:fs.​​createWriteStream不是函数 - Uncaught TypeError: fs.createWriteStream is not a function 类型错误:fs.createWriteStream 不是 Node 中的 function - TypeError: fs.createWriteStream is not a function in Node ExcelJS writeFile 不起作用:Uncaught TypeError: fs.createWriteStream is not a function - ExcelJS writeFile not working: Uncaught TypeError: fs.createWriteStream is not a function 错误TypeError:fs.​​createWriteStream不是函数Angular 6 GIF导出 - ERROR TypeError: fs.createWriteStream is not a function Angular 6 GIF export Node.js fs.createWriteStream 未定义 function - Node.js fs.createWriteStream undefined function 我如何使用“ stream.pipe(fs.createWriteStream())” - How do I use “stream.pipe(fs.createWriteStream())” Node.js:如何使用fs.createWriteStream创建具有755权限的文件 - Node.js: How to create file with 755 permissions with fs.createWriteStream 使用fs.createWriteStream在Node.js中写入大文件 - Writing large file in Nodejs using fs.createWriteStream 是否可以使用 fs.createWriteStream 在文件中间写入文本? (或一般在nodejs中) - Is it possible to write text in the middle of a file with fs.createWriteStream ? (or in nodejs in general) 自动关闭“fs.createWriteStream()”以避免潜在的 memory 泄漏 - Auto close of “fs.createWriteStream()” to avoid potential memory leak
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM