I'm trying to understand how async/await works in conjunction together with 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;
}
const time = latestTime(); // Promise { <pending> }
As far as I understand, await should be blocking and in the code above it seemingly blocks returning an object bl
with the primitive timestamp
. Then, my function returns the primitive value, however the time variable is set to a pending promise instead of that primitive. What am I missing?
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
});
...though if you're doing this at the top level of a JavaScript module, all modern environments now support top-level await
in modules:
const time = await latestTime();
(Note that if that promise is rejected, your module will fail to load. If your module can work meaningfully even if the promise fails, be sure to wrap that in try
/catch
to handle promise rejection.)
It might (or might not) throw some light on things to see, in explicit promise callback terms, how the JavaScript engine handles your async
function under the covers:
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:
new Promise
(the promise executor function) gets called synchronously by new Promise
.
web3.eth.getBlock
is called synchronously to start the work.new Promise
and converted into a promise rejection.then
) will get caught and converted into a rejection.