NodeJS Plotly - how to wait for getImage to finish before continuing

Deadly 提交于 2021-02-16 15:27:26

问题


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
}

回答1:


Welcome to Stack Overflow!

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

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.

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.

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);
    });
}


来源:https://stackoverflow.com/questions/58616012/nodejs-plotly-how-to-wait-for-getimage-to-finish-before-continuing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!