异步函数返回承诺,而不是值

问题描述 投票:0回答:3

我试图理解 async/await 如何与 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> }

据我了解,await 应该是阻塞的,并且在上面的代码中,它似乎阻止使用原语

bl
返回对象
timestamp
。然后,我的函数返回原始值,但是时间变量设置为待处理的承诺而不是该原始值。我错过了什么?

javascript promise async-await primitive
3个回答
30
投票

异步前缀是 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;
}

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

28
投票

async
函数总是返回一个promise。这就是它报告异步工作完成情况的方式。如果您在另一个
async
函数中使用它,则可以使用
await
等待其承诺解决,但在非
async
函数中(通常在顶层或在事件处理程序中),您必须直接使用 Promise,例如:

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

...尽管如果您在 JavaScript 模块的顶层执行此操作,则所有现代环境现在都支持模块中的顶层

await
:

const time = await latestTime();

(请注意,如果该 Promise 被拒绝,您的模块将无法加载。如果即使 Promise 失败您的模块也可以有意义地工作,请务必将其包装在

try
/
catch
中以处理 Promise 拒绝。)


可能(或可能不会)以显式承诺回调术语的形式揭示了一些要了解的事情,即JavaScript引擎如何在幕后处理您的

async
函数:

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

一些重要的注意事项:

  • 您传递给
    new Promise
    的函数(promise executor 函数)由
    new Promise
    同步调用。
    • 这就是操作开始的原因,
      web3.eth.getBlock
      被同步调用来开始工作。
  • Promise 执行器中抛出的任何错误(等)都会被
    new Promise
    捕获并转换为 Promise 拒绝。
  • promise 回调中抛出的任何错误(等)(就像我们传递的错误
    then
    )都将被捕获并转换为拒绝。

12
投票
无论如何,

async
函数都会返回
Promise
。返回值将是`Promise,所以在你的情况下它将是:

async function latestTime(): Promise<some primitive> {
  const bl = await web3.eth.getBlock('latest');
  return bl.timestamp;
}

因此,您还可以使用它的功能,例如:

const time = await latestTime();

但是为了获得有关

async/await
功能的一般看法,最好阅读文档。

© www.soinside.com 2019 - 2024. All rights reserved.