3

I need to get a value of an asynchronous function. I tried to use Promise, but that does not work:

const res = new Promise(function (resolve, reject) {
  gm(readStream).size({ bufferStream: true }, function (err, size) {
    if (!err) resolve(size)
  })
})
console.log(res)

The result I get is Promise { <pending> }

user3142695
  • 15,844
  • 47
  • 176
  • 332
  • 2
    Using promises doesn't make your code synchronous. `res.then(function (ret) { console.log(ret); })` – Keith Sep 08 '17 at 16:23
  • 9
    Don't need to be sarcastic here @adeneo. You were a beginner once. – Duncan Thacker Sep 08 '17 at 16:25
  • 1
    Well, you've asked question before where you've actually used promises, and async/await, and callbacks, so you clearly know what asynchronous is, unless you're just copy/pasting random questions for the fun? – adeneo Sep 08 '17 at 16:42
  • I mean -> https://stackoverflow.com/questions/45948918/nodejs-restify-how-can-i-recieve-file-upload-in-api come on ! – adeneo Sep 08 '17 at 16:44
  • Obviously I've some problems understanding those things. I think for me there are some misunderstandings. That's why I'asking this basic question. Still I'm not able to convert the answer of nadavvadan to a async/await version – user3142695 Sep 08 '17 at 17:36

2 Answers2

10

Promises are an abstraction for callbacks, not magic. They can't make asynchronous code synchronous.

The correct solution is:

const res = new Promise(function (resolve, reject) {
  gm(readStream).size({ bufferStream: true }, function (err, size) {
    if (err) reject(err);
    else resolve(size);

  })
});

res.then(function(promiseResolutionValue) {
    console.log(res)
})

You could also use async / await here:

const getSize = readStream => {
    return new Promise(function (resolve, reject) {
    gm(readStream).size({ bufferStream: true }, function (err, size) {
      if (err) reject(err);
      else resolve(size);
    })
  });
}


let printSize = async readStream => {
  console.log(`Size is ${await getSize(readStream)}`);
}

Or, if you're using NodeJS (Version 8+), you might be able to adapt your function to use util.promisify.
Other Promise libraries, such as Bluebird, also offer such functions, to easily convert 'standard' node-style functions (functions that have a callback with err, data as arguments) into promise-returning equivalents.

Or just use the callback.

nadavvadan
  • 3,930
  • 1
  • 17
  • 29
1

Your code should be looked like this:

const res = new Promise(function (resolve, reject) {
  gm(readStream).size({ bufferStream: true }, function (err, size) {
    if (!err) resolve(size)
    else reject(err)
  })
})

function onResolved(data) {
  console.log('data: ', data);
}

function onRejected(err) {
  console.log('err:', err);
}

res.then(onResolved, onRejected);

Promise does not make your code synchronous, it lets you control when you want to get the result, not immediately like callback style.

thelonglqd
  • 1,805
  • 16
  • 28