Tim*_*ope 17 javascript asynchronous node.js async-await es6-promise
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;
}
Run Code Online (Sandbox Code Playgroud)
能够处理这样的错误非常好.但是我想异步获取一个值,我想保护它不被重新分配(例如:数据库会话),但我仍然想使用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.
}
Run Code Online (Sandbox Code Playgroud)
当然你可以在try块中执行函数的其余部分,但是然后你冒着被捕到的错误,应该让它掉进别的地方.(例如,我在编写测试时遇到了这样的挑战,其中测试失败等错误需要回退到测试套件,但我想自己处理驱动程序实例化.也许我在这里遇到某种反模式而不让这些错误回落到测试套件.)
简单的答案显然是不要在这里使用那种模式.改为使用Promises和回调.或使用var,并避免块作用域const和let.但我喜欢重新分配保护的好处和其他考虑因素的阻止范围.
[问题]:有没有办法将await/async try/catch块包装到每个函数中?似乎是一个潜在的解决方案,但并不像我那样可读try/catch.事实上,try/catch不破坏功能范围,我可以return在一个try/catch块中使用,这似乎更符合async/await为异步代码带来更具程序性的逻辑的精神.
理想情况下,你会想这样做const x = await y() catch (err)或const x = await y() || fail不过,我想不出有相似的流程这是语法正确的事情.
更新:正如@jmar777所建议的另一个选择是:
const x = await y().catch(() => {/*handle errors here*/})
Run Code Online (Sandbox Code Playgroud)
这可能是我在实践中最后两个例子中找到的最接近的.但它打破了return上述示例中阻止下游执行的范围.这是处理事物的一种很好的同步方式.
每种解决方案都有其权衡.
我已经let在功能块的顶部手动提升变量作为工作解决方案(如jmar777的答案中所述)仍然是一个有趣的问题,看看各种方法,所以我现在将问题保持开放.
jma*_*777 11
您可能对使用的好处有误解const.使用const声明分配值不会使该值不可变,它只是意味着不能更改或重新声明该常量的值:
const声明创建对值的只读引用.它并不意味着它拥有的值是不可变的,只是不能重新赋值变量标识符.例如,在内容是对象的情况下,这意味着对象本身仍然可以被更改.(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const)
在您的示例中,您可能最好result在try/catch之外手动提升绑定:
async function () {
let result;
try {
result = await get_session()
} catch (err) {
console.log(`This block should catch any
instantiation errors.`)
}
// do whatever else you need with result here...
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是重构代码,使您根本不需要依赖try/catch.例如:
async function () {
const result = await get_session().catch(someRejectionHandler);
// do whatever else you need with result here...
}
Run Code Online (Sandbox Code Playgroud)
请注意,您的下游代码需要优雅地处理get_session()被拒绝的情况,并且result不会根据成功的响应进行初始化.这与您的初始示例没有什么不同,但在扫描代码时可能并不那么明显.
几年后回到这个问题,我想到了一个更简单的答案,回想起来,我不明白为什么我对一个小的 try/catch 对感兴趣,然后当我在它之外执行更多逻辑时可以简单地执行所有逻辑并在 try 语句内返回。
\n\n以问题中的例子并应用该结构将是:
\n\n async function () {\n try {\n const result = await get_session()\n // Do what needs to be done and then:\n return result\n } catch (err) {\n console.log(`This block should catch any\n instantiation errors.`)\n return false\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n如果您需要从 catch 块中的 try 块访问任何内容,则会引发错误。当我问这个问题时,可能有一个原因我需要移出 try 范围,但我不能\xe2\x80\x99t 看到需要回顾的场景。如果您要使用 try/catch/finally 并在 finally 中返回,则此解决方案将\xe2\x80\x99 不起作用。但我不认为我在野外遇到过这种模式。
\n| 归档时间: |
|
| 查看次数: |
6730 次 |
| 最近记录: |