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

时间:2018-07-14 11:56:44

标签: javascript promise async-await primitive

我试图了解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> }

问题

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

4 个答案:

答案 0 :(得分:5)

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功能的一般视图,最好阅读文档。

答案 1 :(得分:4)

异步前缀是Promises的一种包装。

import openpyxl
wb = openpyxl.load_workbook('C:\\Users\\Excel\\Desktop\\Book1.xlsx')
ws = wb.get_sheet_by_name('Sheet1')
for row in ws.iter_rows('A{}:A{}'.format(ws.min_row,ws.max_row)):
    for cell in row:
        if isinstance(cell.value, str):
            print('string')
        elif isinstance(cell.value, int):
            print('integer')
        elif isinstance(cell.value, float):
            print('float')

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

答案 2 :(得分:4)

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引擎正在支持顶级awaitWebpack 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执行程序函数)被new Promise同步调用。
    • 这就是操作开始的原因,web3.eth.getBlock被同步调用以开始工作。
  • 在承诺执行器中引发的任何错误(等)都被new Promise捕获并转换为承诺拒绝。
  • 在promise回调(例如我们正在传递的then中)中引发的任何错误(等)都将被捕获并转换为拒绝。

答案 3 :(得分:0)

简短的回答:代替

result = await asyncFunction();

使用:

result = await asyncFunction().then(value => value);