1

I know you can access a Promise’s value inside the .then method like the following code:

const Promise = require("bluebird");
const fs = Promise.promisifyAll(require('fs'));
const mergeValues = require('./helper').mergeValues;


fs.readFileAsync('./index.html', {encoding: "utf8"})
    .then((data) => {
        return mergeValues(values, data); //async function that returns a promise
    })
    .then((data) => {
        console.log(data);
    });

In the above example, I’m reading from a file, merging the data with some values, and then logging the data to the console.

But how about returning the value from a function, as you normally would in a synchronous function? If I follow this comment on synchronous inspection, I think the code should look like this:

function getView(template, values) {
    let file = fs.readFileAsync('./' + template, {encoding: "utf8"});
    let modifiedFile = file.then((data) => {
            return mergeValues(values, data);
        });
    return modifiedFile.then((data) => {
        return modifiedFile.value();
    });
}
console.log(getView('index.html', null));

But for some reason, it’s not working. All I’m getting in the console is the Promise object itself, not the value. And when I add the .isFulfilled method on modifiedFile, it outputs to true. So I’m not sure what I’m doing incorrectly.

Community
  • 1
  • 1
Anup Sheth
  • 269
  • 1
  • 3
  • 11
  • You can never ever return a value from async. Ever. Canonical answer: [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call). – Amadan Jan 30 '17 at 04:54
  • Once you commit to an async call everything past that depends on any results of that operation is by definition async as well. That is, if you use a Promise in your function and you need to get something back from it, return a promise. You can't wait around. – tadman Jan 30 '17 at 05:01

1 Answers1

2

Promises don't work that way. They are asynchronous by nature, so you can't interact with them in the same way you do with synchronous code.

That means you have to use the then method to get at the value:

function getView(template, values) {
    let file = fs.readFileAsync('./' + template, {encoding: "utf8"});
    let modifiedFile = file.then((data) => {
            return mergeValues(values, data);
        });
    return modifiedFile.then((data) => {
        return modifiedFile.value();
    });
}
// This won't work
// console.log(getView('index.html', null)); 

// instead:
getView('index.html', null).then(function (view) {
    console.log(view);
});

So I’m not sure what I’m doing incorrectly.

You're not doing anything incorrectly, actually. You just can't use promises like a normal return value from a function. Period.

rossipedia
  • 56,800
  • 10
  • 90
  • 93