【发布时间】:2017-06-02 08:58:50
【问题描述】:
ES2017 async/await 的一个很好的模式是:
async function () {
try {
var result = await some_promised_value()
} catch (err) {
console.log(`This block would be processed in
a reject() callback with promise patterns
but this is far more intuitive`)
return false // or something less obtuse
}
result = do_something_to_result(result)
return result;
}
能够处理这样的错误真是太好了。但是假设我想异步获取一个值,我想保护它不被重新分配(例如:数据库会话),但我仍然想使用 async/await 模式(纯粹是因为我认为它更直观)。
以下内容不起作用,因为 const 是块作用域:
async function () {
try {
const result = await get_session()
} catch (err) {
console.log(`This block should catch any
instantiation errors.`)
return false
}
// Can't get at result here because it is block scoped.
}
当然,您可以在 try 块中执行其余的函数,但是您可能会遇到错误,而这些错误应该会在其他地方漏掉。 (例如,我在编写测试时遇到了这个挑战,其中像测试失败这样的错误需要退回到测试套件,但我想自己处理驱动程序实例化。也许我在这里陷入了某种反模式,不让这些错误退回到测试套件。)
简单的答案显然是不要在这里使用那种模式。改用 Promise 和回调。或者使用var 并避免块作用域const 和let。但我喜欢重新分配保护和阻止范围的好处。
[问题]:Is there a way to wrap an await/async try/catch block to every function? 似乎是一种潜在的解决方案,但不像try/catch 那样可读。 try/catch 不会破坏函数范围并且我可以在 try/catch 块内使用 return 这一事实在我看来更符合 async/await 的精神,为异步带来了更具程序性的逻辑代码。
理想情况下,您希望执行const x = await y() catch (err) 或const x = await y() || fail 之类的操作,但我想不出任何语法正确的类似流程。
更新: 正如@jmar777 所建议的,下面的另一种选择是:
const x = await y().catch(() => {/*handle errors here*/})
这可能是我在实践中发现的与最后两个示例最接近的。但它打破了上面示例中阻止下游执行的return 范围。这是一种很好的类似同步的处理方式。
每个解决方案都有其权衡。
我已经在功能块顶部手动提升了带有let 的变量作为一个工作解决方案(如 jmar777 的回答中所述)仍然是一个有趣的问题,可以看到各种方法,所以我会留下这个问题暂时。
【问题讨论】:
-
async/await 不是 ES7 (ES2016) 的一部分。它将成为今年发布的 ES2017 的一部分。
-
一个类似的答案here希望能帮到你。
标签: javascript node.js asynchronous async-await es6-promise