Async function returning promise, instead of value

An async function always returns a promise. That's how it reports the completion of its asynchronous work. If you're using it in another async function, you can use await to wait for its promise to settle, but in a non-async function (often at the top level or in an event handler), you have to use the promise directly, e.g.:

latestTime()
.then(time => {
    console.log(time);
})
.catch(error => {
    // Handle/report error
});

If you're doing this at the top level of a JavaScript module, some environments now support the upcoming top-level await in modules:

const time = await latestTime();

JavaScript engines are getting support for top-level await, and Webpack has experimental support for it, for instance.


Here's a rough translation of your async function in explicit Promise terms:

function latestTime() {
    return new Promise((resolve, reject) => {
        web3.eth.getBlock('latest')
        .then(bl => {
            console.log(bl.timestamp);
            console.log(typeof bl.timestamp.then == 'function');
            resolve(bl.timestamp);
        })
        .catch(reject);
    });
}

Some important notes on that:

  • The function you pass to new Promise (the promise executor function) gets called synchronously by new Promise.
    • Which is why the operation starts, web3.eth.getBlock is called synchronously to start the work.
  • Any error (etc.) thrown within the promise executor gets caught by new Promise and converting into a promise rejection.
  • Any error (etc.) thrown within a promise callback (like the one we're passing then) will get caught and converted into a rejection.

Async prefix is a kind of wrapper for Promises.

async function latestTime() {
    const bl = await web3.eth.getBlock('latest');
    console.log(bl.timestamp); // Returns a primitive
    console.log(typeof bl.timestamp.then == 'function'); //Returns false - not a promise
    return bl.timestamp;
}

Is the same as

function latestTime() {
    return new Promise(function(resolve,success){
        const bl = web3.eth.getBlock('latest');
        bl.then(function(result){
            console.log(result.timestamp); // Returns a primitive
            console.log(typeof result.timestamp.then == 'function'); //Returns false - not a promise
            resolve(result.timestamp)
        })
}