使用异步/等待与Promise

4

我正在学习TypeScript中的异步/等待功能,对此有一些问题。我编写了以下函数以从Blob获取ArrayBuffer。

async function readAsArrayBuffer(blob: Blob): Promise<ArrayBuffer> {
    return new Promise<ArrayBuffer>((resolve, reject) => {
        let reader = new FileReader();
        reader.addEventListener('load', e => resolve((<FileReader>e.target).result));
        reader.addEventListener('error', e => reject((<FileReader>e.target).error));
        reader.readAsArrayBuffer(blob);
    });
}

所以...

  1. 在这个函数之前,我真的需要使用 async 关键字吗?我认为它没有什么作用...
  2. 我应该在 Promise 执行函数的范围内创建新的 FileReader,还是在 readAsArrayBuffer 的范围级别上创建?(...或者没有关系?)
  3. 我写的是三个嵌套的函数,有问题吗? :-)
2个回答

4

我真的需要在这个函数之前加上async关键字吗?我觉得它没有任何作用...

不需要。只有当你在函数体内使用await时,才真正需要使用async关键字。

我应该在Promise执行器函数范围内创建新的FileReader还是在readAsArrayBuffer范围内创建?(...或者没关系?)

我建议将大部分实际代码放在执行器函数内部。优点是,如果出现同步异常(例如,如果new FileReader()在构造时抛出异常),执行器将捕获并将其转换为异步Promise拒绝。如果将其放在执行器函数外部,则函数将抛出同步异常。这会让使用变得混乱,因为您必须单独处理同步和异步异常。

我写的是两个嵌套在函数中的函数。我做错了什么吗? :-)

没问题。当你在非Promise API周围编写Promise包装器时,这是一种常见的模式。优点是,现在你可以使用await来使用这个包装器,并避免在代码的其他部分中嵌套函数。 :-)


@trincot 是的,请参考MDN: “如果执行器函数中抛出错误,则 Promise 被拒绝。执行器的返回值被忽略。” 请注意,当您从开发控制台运行此代码时,Chrome会记录“未捕获的(在 promise 中)my error”,但这实际上是因为默认的未捕获的 promise 拒绝处理程序。尝试在其周围放置try..catch以查看与仅使用throw“my error”相比的差异。 - Mattias Buelens
确实,你说得对。我在FireFox中看到的输出比在Chrome中看到的不够清晰。 - trincot

3
  1. 我真的需要在这个函数之前加上async关键字吗?我认为它没有任何作用...

不需要,只有当函数使用await关键字时才需要使用async。在您的函数中,该函数会同步执行完成,而不是异步执行。异步部分仅在触发回调时才存在,这不是async关键字的关注点。

  1. 我应该在Promise执行程序函数作用域内创建新的FileReader还是在readAsArrayBuffer作用域级别?(...或者无所谓?)

最佳实践是在需要执行任务的最小范围内定义变量。虽然两种方式都可以工作,但现在这种方式更好。

  1. 我写的是一个嵌套的函数,其中包含两个函数。我做错了什么吗? :-)

没有问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接