异步函数返回承诺,而不是值
Posted
技术标签:
【中文标题】异步函数返回承诺,而不是值【英文标题】:Async function returning promise, instead of value 【发布时间】:2021-09-30 14:59:24 【问题描述】:我试图了解 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
。然后,我的函数返回原始值,但是时间变量设置为待处理的承诺而不是该原始值。我错过了什么?
【问题讨论】:
这就是异步函数的作用——阅读specawait should be blocking
no - javascript 中的阻塞代码是一个“坏主意”™,async/await 与阻塞无关
Every async function
返回一个承诺,这样你就可以在其中 await
其他承诺,这就是重点
这能回答你的问题吗? async/await implicitly returns promise?
【参考方案1】:
async
函数总是返回一个承诺。这就是它报告其异步工作完成的方式。如果你在另一个 async
函数中使用它,你可以使用 await
等待它的承诺解决,但在非async
函数中(通常在顶层或事件处理程序中),你必须直接使用promise,例如:
latestTime()
.then(time =>
console.log(time);
)
.catch(error =>
// Handle/report error
);
如果您在 JavaScript 模块的顶层执行此操作,一些环境现在支持即将推出的 top-level await
in modules:
const time = await latestTime();
例如,JavaScript 引擎正在获得对*** await
和 Webpack has experimental support for it 的支持。
这是您的 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);
);
一些重要说明:
传递给new Promise
的函数(promise executor 函数)被new Promise
同步调用。
这就是操作开始的原因,web3.eth.getBlock
被同步调用以开始工作。
在 Promise 执行器中抛出的任何错误(等)都会被 new Promise
捕获并转换为 Promise 拒绝。
promise 回调中抛出的任何错误(等等)(例如我们传递的then
)都将被捕获并转换为拒绝。
【讨论】:
【参考方案2】: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
功能的一般视图,最好阅读文档。
【讨论】:
【参考方案3】:异步前缀是 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
函数的翻译存在一些问题。用非常广泛的概念术语来说是可以的,但不能正确处理拒绝,有语法错误,并且给传递给承诺执行器的第二个参数(用于 拒绝承诺)... :-)以上是关于异步函数返回承诺,而不是值的主要内容,如果未能解决你的问题,请参考以下文章
Javascript - 异步等待和获取 - 返回值,而不是承诺?
为啥我的异步函数返回 Promise <pending> 而不是一个值?