search

Home  >  Q&A  >  body text

Asynchronous functions return Promises, not values

I'm trying to understand how async/await works with Promise.

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> }

From what I understand, await is supposed to be blocking, and in the code above, it seems to prevent using the primitive timestamp to return an object bl . My function then returns the original value, but the time variable is set to the pending promise instead of that original value. What did I miss?

P粉464208937P粉464208937406 days ago534

reply all(2)I'll reply

  • P粉099985373

    P粉0999853732023-10-20 14:57:49

    Asynchronous prefix is ​​a 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;
    }

    the same with

    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)
            })
    }

    reply
    0
  • P粉002023326

    P粉0020233262023-10-20 12:58:06

    async Functions always return a Promise. This is how it reports the completion of asynchronous work. If you're using it inside another async function, you can use await to wait for its promise to resolve, but in a non-async function (usually at the top level or in an event handler), you have to use Promise directly, for example:

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

    ...However, if you do 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 this Promise is rejected, your module will fail to load. If your module works meaningfully even if the Promise fails, be sure to wrap it in a try/catch Handles promise rejection.)


    It may (or may not) reveal something in the form of explicit promise callback terms that gives us an idea of ​​how the JavaScript engine handles your async function under the hood:

    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:

    • The function you pass to new Promise (the promise executor function) is called synchronously by new Promise.
      • This is why the operation starts, calling web3.eth.getBlock synchronously to start the work.
    • Any errors (etc.) thrown in the Promise executor will be caught by the new Promise and converted into a Promise rejection.
    • Any errors thrown in the Promise callback (such as the then errors we pass) will be caught and converted into rejections.

    reply
    0
  • Cancelreply