异步函数返回promise,而不是值

use*_*162 5 javascript primitive promise async-await

我试图了解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> }
Run Code Online (Sandbox Code Playgroud)

问题

据我了解,await应该被阻塞,并且在上面的代码中,它似乎阻塞了返回bl带有基本对象的对象timestamp。然后,我的函数返回原始值,但是时间变量设置为待处理的promise,而不是原始值。我想念什么?

T.J*_*der 11

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

latestTime()
.then(time => {
    console.log(time);
})
.catch(error => {
    // Handle/report error
});
Run Code Online (Sandbox Code Playgroud)

如果您在 JavaScript 模块的顶层执行此操作,则某些环境现在支持即将到来的顶层await模块

const time = await latestTime();
Run Code Online (Sandbox Code Playgroud)

JavaScript 引擎正在获得对 top-level 的支持,例如awaitWebpack 对它有实验性支持


这是您的async函数在明确的 Promise 术语中的粗略翻译:

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);
    });
}
Run Code Online (Sandbox Code Playgroud)

一些重要的注意事项:

  • 您传递给的函数new Promisepromise 执行器函数)被new Promise.
    • 这就是为什么操作开始,web3.eth.getBlock被同步调用以开始工作。
  • 承诺执行器中抛出的任何错误(等)都会被捕获new Promise并转换为承诺拒绝。
  • 在承诺回调中抛出的任何错误(等)(如我们正在传递的错误then)都将被捕获并转换为拒绝。


小智 9

异步前缀是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;
}
Run Code Online (Sandbox Code Playgroud)

是相同的

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)
        })
}
Run Code Online (Sandbox Code Playgroud)

  • 附带说明:“async”函数的翻译存在一些问题。从非常广泛的概念术语来看,这是可以的,但是不能正确处理拒绝,有语法错误,并且给传递给承诺执行器的第二个参数(用于 * *拒绝**承诺)...:-) (4认同)

Ole*_*sii 5

async函数Promise仍然会返回。返回值将是Promise,因此您的情况将是:

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

因此,进一步可以使用它的功能,例如:

const time = await latestTime();
Run Code Online (Sandbox Code Playgroud)

但是,要获得有关async/await功能的一般性看法,最好阅读文档。