NodeJS Plotly - 如何在继续之前等待 getImage 完成继续、如何在、NodeJS、Plotly

2023-09-06 14:31:47 作者:草莓熊

所以,我想要完成的基本上是:使用 NodeJS 生成绘图并为 NodeJS 绘图并将其放入我的文件系统(使用 getImage),然后继续处理图像.我的问题是,该函数在完成并将图像放入我的文件系统之前返回.所以我的结果基本上是在我调用 generate_plot() 之后,该文件还不存在并且我得到一个错误.现在我的问题是:我如何等待 generate_plot() 完成并将图像放入我的文件系统之前继续使用这个图像/使用这个图像?

So, what I am trying to accomplish is basically: Generating a plot by using NodeJS and plotly for NodeJS and getting it into my filesystem (with getImage), and proceeding with the image afterwards. My problem is, that the function returns before finishing and getting the image into my filesystem. So my result is basically that after I'm calling generate_plot(), the file does not exist yet and I'm getting an error. Now onto my question: How do I wait for generate_plot() to finish and to getting the image into my filesystem before continuing and using this image/to use this image?

const fs = require("fs");
var plotly = require('plotly')(username, api_key);

function generate_plot(){
    var trace = {
      type: 'bar',
      x: ['Mario', 'Luigi', 'Bowser'],
      y: [50000, 10000, 2000],
      marker: {color: ["red", "green", "darkblue"]},
    };

    var layout = {
      plot_bgcolor: 'rgb(52, 54, 60)',
      paper_bgcolor: 'rgb(52, 54, 60)',
    };

    var chart = {data: [trace], layout: layout};

    var pngOptions = {format: 'png', width: 1000, height: 500};

    plotly.getImage(chart, pngOptions, function (err, imageData) {
        if (err) throw err
        var pngStream = fs.createWriteStream('test.png');
        imageData.pipe(pngStream);
    })
}

function run(){
    generate_plot()
    // proceed with the generated plot which should be in the filesystem
}

推荐答案

欢迎来到 Stack Overflow!

Welcome to Stack Overflow!

我已经删除了我之前的答案,因为(正如您正确指出的那样)他们没有解决全部问题.

I have removed my previous answers, because (as you correctly pointed out) they didn't solve the full problem.

在我们返回 generate_plot() 函数之外的控制之前,需要完成两个异步任务:从 Plotly 检索数据,并将该内容写入磁盘.

There are two asynchronous tasks that need to complete before we return control outside of the generate_plot() function: retrieving data from Plotly, and writing that content to disk.

下面的示例调用 generate_plot(),然后(作为验证文件是否真的在磁盘上的测试)它立即将 test.png 复制到 test2.png.因为这会导致两个文件大小相同,这表明 fs.copyFileSynctest.png 文件完全在磁盘上之前不会运行.

The example below calls generate_plot(), and then (as a test to validate whether the file is really on disk) it immediately copies test.png to test2.png. Because this results in both files being the same size, this demonstrates that the fs.copyFileSync is not running until the test.png file is fully on disk.

我确实稍微更改了一些变量名,但这现在应该可以了.

I did change some of your variable names slightly, but this should work now.

为了等待文件流完成,我参考了这个问题:node.js 中与 fs.createWriteStream 关​​联的事件

For waiting for the file stream to finish, I reference this question: event associated with fs.createWriteStream in node.js

function generate_plot() {
  return new Promise((resolve, reject) => {
    var trace = {
      type: 'bar',
      x: ['Mario', 'Luigi', 'Bowser'],
      y: [50000, 10000, 2000],
      marker: { color: ["red", "green", "darkblue"] },
    };

    var layout = {
      plot_bgcolor: 'rgb(52, 54, 60)',
      paper_bgcolor: 'rgb(52, 54, 60)',
    };

    var chart = { data: [trace], layout: layout };

    var pngOptions = { format: 'png', width: 1000, height: 500 };

    plotly.getImage(chart, pngOptions, (err, imageStream) => {
      if ( err ) return reject(err);
      var fileStream = fs.createWriteStream('test.png');
      imageStream.pipe(fileStream);
      fileStream.on('error', reject);
      fileStream.on('finish', resolve);
    });
  });
}

function run() {
  generate_plot()
    .then(() => {
      fs.copyFileSync('test.png', 'test2.png');
      console.log('done');
    })
    .catch(err => {
      console.log(err);
    });
}
 
精彩推荐