我试图了解 async/await 如何与 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> }
据我所知,await 应该是阻塞的,在上面的代码中,它似乎阻塞了返回一个带有原始
bl
的对象timestamp
。然后,我的函数返回原始值,但是时间变量被设置为一个挂起的承诺而不是那个原始值。我错过了什么?
Async 前缀是 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)
})
}
async
函数总是返回一个承诺。这就是它报告其异步工作完成的方式。如果你在另一个 async
函数中使用它,你可以使用 await
等待它的承诺来解决,但是在非 async
函数(通常在顶层或事件处理程序中),你必须直接使用 promise,例如:
latestTime()
.then(time => {
console.log(time);
})
.catch(error => {
// Handle/report error
});
...虽然如果你在 JavaScript 模块的顶层执行此操作,所有现代环境现在都支持 top-level
await
在模块中:
const time = await latestTime();
(请注意,如果该承诺被拒绝,您的模块将无法加载。如果您的模块即使承诺失败也能有意义地工作,请务必将其包装在
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 执行器 函数)被 new Promise
同步调用。
web3.eth.getBlock
被同步调用以开始工作。new Promise
捕获并转换为 promise 拒绝。then
)都将被捕获并转换为拒绝。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
功能的一般观点,阅读文档会更好。