yanivtwin
yanivtwin

Reputation: 625

wait for callback result before continue node js

I have a service written in node js. It's job is to connect to azure storage download a file and returning it as base64.

here's what I did so far:

` var azure = require('azure-storage');
const fs = require('fs');
var fileService = azure.createFileService('microsoftdata');
var test = await fileService.getFileToStream('sharename', '', filename, fs.createWriteStream(filename), async function (error, result, response) {
  if (!error) {
    console.log('result ' + JSON.stringify(result, null, 4));
    var bitmap = await fs.readFileSync(filename);
    return bitmap.toString('base64');
    // var str = getFileAsBase64(filename);
    // console.log('str - ' + str);

    // return str;
    // file downloaded
  }
  else {
    console.log('error - ' + JSON.stringify(error, null, 4));
  }

});
console.log('test - ' + test);`

What's happening now is : downloading a file -> returning data of file in var 'test' -> finished download entering the callback and returning base64 to nowhere.

What I want to achieve is : downloading a file -> waiting for finish -> finished and enter callback -> return base64 to test or another var in his scope.

Thanks.

Upvotes: 0

Views: 149

Answers (2)

Tony
Tony

Reputation: 910

try creating a promise and resolve it

//Basic
function x() {
  var promise = new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve("done!");
    });
  });
  return promise;
}
async function y() {
  var y = await x();
  console.log("y", y);
}
y();

//Implementation
var azure = require('azure-storage');
const fs = require('fs');
var fileService = azure.createFileService('microsoftdata');
var test = new Promise(function(resolve, reject) {
  fileService.getFileToStream('sharename', '', filename, fs.createWriteStream(filename), async function(error, result, response) {
    if (!error) {
      console.log('result ' + JSON.stringify(result, null, 4));
      var bitmap = await fs.readFileSync(filename);
      resolve(bitmap.toString('base64'));
    } else {
      console.log('error - ' + JSON.stringify(error, null, 4));
    }

  });
});
console.log('test - ' + test);

Upvotes: 1

Colin
Colin

Reputation: 2487

So there are a couple possible issues here, but I am not an Azure expert and the documentation isn't clear on this so I'll just give you both.

  1. Does getFileToStream actually return a promise? It doesn't say it does in the documentation so I can't tell. If not and you still want to use async/await, you'll need to wrap it in a new Promise(). Something like this:
var azure = require('azure-storage');
const fs = require('fs');
var fileService = azure.createFileService('microsoftdata');
var test = await new Promise((res, rej) => {
    fileService.getFileToStream('sharename', '', filename, fs.createWriteStream(filename), async function (error, result, response) {
        if (!error) {
            console.log('result ' + JSON.stringify(result, null, 4));
            var bitmap = await fs.readFileSync(filename);
            res(bitmap.toString('base64'));
            // var str = getFileAsBase64(filename);
            // console.log('str - ' + str);

            // return str;
            // file downloaded
        }
        else {
            rej('error - ' + JSON.stringify(error, null, 4));
        }
    });
})

console.log('test - ' + test);
  1. Returning bitmap.toString('base64) may not set the value of test. I would recommend initializing test before awaiting getFileToStream and then setting its value within the callback function. Something like this:
var azure = require('azure-storage');
const fs = require('fs');
var fileService = azure.createFileService('microsoftdata');
var test
await fileService.getFileToStream('sharename', '', filename, fs.createWriteStream(filename), async function (error, result, response) {
  if (!error) {
    console.log('result ' + JSON.stringify(result, null, 4));
    var bitmap = await fs.readFileSync(filename);
    test = bitmap.toString('base64');
    // var str = getFileAsBase64(filename);
    // console.log('str - ' + str);

    // return str;
    // file downloaded
  }
  else {
    console.log('error - ' + JSON.stringify(error, null, 4));
  }

});
console.log('test - ' + test);

Upvotes: 1

Related Questions