javascript - 如何用 promise 关闭文件句柄?

标签 javascript node.js canvas promise async-await

我正在尝试使用 canvas 模块在 node.js 脚本中创建一个 PNG 文件。

我有一个文件 image.js 来处理图像创建:

const { createCanvas, loadImage } = require('canvas');
const fs = require('fs');

function generateImage(param1, param2) {
  const canvas = createCanvas(4096, 4096);
  const ctx = canvas.getContext('2d');
  // ...
  return new Promise(function (resolve, reject) {
    loadImage('base.png').then((image) => {
      ctx.drawImage(image, 40, 40, 200, 200);

      let out = fs.createWriteStream(__dirname + '/temp.png');
      let stream = canvas.pngStream();

      stream.on('data', function (chunk) {
        out.write(chunk);
      });

      stream.on('end', function () {
        console.log('saved png');
        out.close(); // i probably don't need both, but neither seems to work properly...
        out.end();
        resolve();
      });
    });
  });
}

module.exports = generateImage;

当我将 generateImage('a', 'b'); 附加到该文件的末尾,然后单独运行它 (node image.js) 时,它按预期工作并生成我的图像。但是,当我尝试从不同的文件(在同一文件夹中)调用它时,文件句柄似乎没有关闭,并且在脚本运行时磁盘上的图像是一个空文件。

main.js(简化版):

const generateImage = require('./image');
const fs = require('fs');

async function main() {
    var stats = fs.statSync("temp.png");
    console.log(stats["size"]); // output: 0, expected: > 0
}

generateImage("text", "text").then(() => main());

我是 node.js 的新手,所以我很可能遗漏了一些明显的东西。

最佳答案

根据 Bergi 的建议,我需要为 out 流的 close 事件添加另一个事件监听器,并且只调用一次 resolve()即被触发。我还链接了 promise ,而不是像问题中那样将它们嵌入。

function generateImage(param1, param2) {
  const canvas = createCanvas(4096, 4096);
  const ctx = canvas.getContext('2d');
  // ...
  return loadImage('base.png').then((image) => new Promise(function (resolve, reject) {
    ctx.drawImage(image, 40, 40, 200, 200);

    let out = fs.createWriteStream(__dirname + '/temp.png');
    let stream = canvas.pngStream();

    stream.on('data', (chunk) => out.write(chunk));
    stream.on('end', () => out.end());
    out.on('close', () => resolve());  // this was missing
  }));
}

关于javascript - 如何用 promise 关闭文件句柄?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51428115/

相关文章:

javascript - 如何在canvas和js中旋转对象;我的例子没有按照我的预期旋转

javascript - HTML 5 Canvas 到视频流不起作用

javascript - 什么是 JSXIdentifier 以及它与 AST 中的 Identifier 有何不同?

javascript - 为什么跟随动画在不同的浏览器中不能按预期工作

javascript - 一行推送item数组并返回item

node.js - 找不到模块 'fs'

javascript - 如何暂停用 js 和 html5 制作的简单 Canvas 游戏?

javascript - 展平嵌套数组后保留元素的索引

javascript - 使用 javascript 将参数发送到 java 应用程序

node.js - 无法让 IISNode、socket.io 和express 一起工作