Search code examples
javascriptnode.jspromisebluebird

How do I return the value of a Promise from a function?


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.


Solution

  • 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.