我试图了解 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 应该是阻塞的,并且在上面的代码中,它似乎阻止使用原语 timestamp
返回对象 bl
。然后,我的函数返回原始值,但是时间变量设置为待处理的承诺而不是该原始值。我错过了什么?
P粉0999853732023-10-20 14:57:49
异步前缀是 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) }) }
P粉0020233262023-10-20 12:58:06
async
函数始终返回一个 Promise。这就是它报告异步工作完成情况的方式。如果您在另一个async
函数中使用它,则可以使用await
来等待其promise解决,但在非async
中函数(通常在顶层或在事件处理程序中),您必须直接使用 Promise,例如:
latestTime()
.then(time => {
console.log(time);
})
.catch(error => {
// Handle/report error
});
...不过,如果您在 JavaScript 模块的顶层执行此操作,则所有现代环境现在都支持 模块中的顶级 await
:
const time = await latestTime();
(请注意,如果该 Promise 被拒绝,您的模块将无法加载。如果即使 Promise 失败您的模块也能有意义地工作,请务必将其包装在 try
/catch 中
处理承诺拒绝。)
它可能(或可能不会)以显式承诺回调术语的形式揭示了一些事情,让我们了解 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
错误)都将被捕获并转换为拒绝。