And*_*rew 8 error-handling node.js coffeescript iced-coffeescript
node.js中的常见做法是将错误消息作为回调函数的第一个参数返回.纯JS(Promise,Step,seq等)中有许多解决这个问题的方法,但它们似乎都不能与ICS集成.什么是正确的解决方案来处理错误而不会失去很多可读性?
例如:
# makes code hard to read and encourage duplication
await socket.get 'image id', defer err, id
if err # ...
await Image.findById id, defer err, image
if err # ...
await check_permissions user, image, defer err, permitted
if err # ...
# will only handle the last error
await
socket.get 'image id', defer err, id
Image.findById id, defer err, image
check_permissions user, image, defer err, permitted
if err # ...
# ugly, makes code more rigid
# no way to prevent execution of commands if the first one failed
await
socket.get 'image id', defer err1, id
Image.findById id, defer err2, image
check_permissions user, image, defer err3, permitted
if err1 || err2 || err3 # ...
Run Code Online (Sandbox Code Playgroud)
Max*_*ohn 12
我通过样式和编码约定来解决这个问题.它确实一直出现.让我们把你的片段放在下面,充实一点,以便我们有一个可行的功能.
my_fn = (cb) ->
await socket.get 'image id', defer err, id
if err then return cb err, null
await Image.findById id, defer err, image
if err then return cb err, null
await check_permissions user, image, defer err, permitted
if err then return cb err, null
cb err, image
Run Code Online (Sandbox Code Playgroud)
你是完全正确的,这是丑陋的,因为你在很多地方短路代码,你需要记住每次返回时调用cb.
您提供的其他片段会产生不正确的结果,因为它们会引入需要序列化的并行性.
我的个人ICS编码约定是:(1)从函数返回一次(控件从结尾处退出); (2)尝试在同一级别的缩进处理错误.以我喜欢的方式重写你拥有的东西:
my_fn = (cb) ->
await socket.get 'image id', defer err, id
await Image.findById id, defer err, image unless err?
await check_permissions user, image, defer err, permitted unless err?
cb err, image
Run Code Online (Sandbox Code Playgroud)
如果socket.get调用出错,则需要检查错误两次,两次都会失败.我不认为这是世界末日,因为它使代码更清晰.
或者,您可以这样做:
my_fn = (autocb) ->
await socket.get 'image id', defer err, id
if err then return [ err, null ]
await Image.findById id, defer err, image
if err then return [ err, null ]
await check_permissions user, image, defer err, permitted
return [ err, image ]
Run Code Online (Sandbox Code Playgroud)
如果你使用autocb,这不是我最喜欢的ICS功能,那么只要你返回/短路函数,编译器就会为你调用autocb.我觉得这种结构更容易出错.例如,想象一下你需要在函数开始时获取一个锁,现在你需要释放它n次.其他人可能不同意.
另外一点,在评论中指出. autocb就像return它只接受一个值一样.如果要在此示例中返回多个值,则需要返回数组或字典. defer做解构任务,以帮助你在这里:
await my_fn defer [err, image]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1114 次 |
| 最近记录: |