英文:
Multiple contexts in a single function: reuse, and cancellation
问题
在一个函数中执行了几个使用各自上下文的任务。如果上下文没有超时,就会显式调用取消函数。类似这样:
ctx, cancel := contextWithTimeout(...)
defer cancel()
doSomethingA(ctx, ...)
// 验证 doSomethingA 没有错误
cancel()
ctx, cancel = contextWithTimeout(...)
defer cancel()
doSomethingB(ctx, ...)
// 验证 doSomethingB 没有错误
cancel()
变量名(ctx
,cancel
)被重复使用,并且每次都手动调用 cancel()
函数,而不是等待 defer。
这种处理多个上下文的方式是否合适?
英文:
There are a few tasks performed in a function that all use their own contexts. The cancel functions are being explicitly called if the context does not time out. Something like this:
ctx, cancel := contextWithTimeout(...)
defer cancel()
doSomethingA(ctx, ...)
// verify no errors from doSomethingA
cancel()
ctx, cancel = contextWithTimeout(...)
defer cancel()
doSomethingB(ctx, ...)
// verify no errors from doSomethingB
cancel()
The names (ctx
, cancel
) are being reused, and the cancel()
function is being manually called every time instead of waiting for the defer.
Is this an appropriate way to handle multiple contexts?
答案1
得分: 1
在这种情况下,你可能会发现一种有用的模式是将代码块包装在不同的闭包中。这样做的主要优点是,你可以使用defer来调用cancel()
,如果有很多分支需要显式调用cancel()
,那么这种方式可能更可取。
根据你的偏好,你可以在闭包内部或外部处理任何返回的错误。
func() {
ctx, cancel := contextWithTimeout(...)
defer cancel()
err := doSomethingA(ctx, ...)
if err != nil {
// 处理错误。
}
}()
err := func() error {
ctx, cancel := contextWithTimeout(...)
defer cancel()
return doSomethingB(ctx, ...)
}()
// 在这里处理doSomethingB的错误。
这种模式对于需要关闭以避免泄漏的资源也很有用,比如HTTP响应体、文件和网络连接。
英文:
A pattern you might find useful in this case is to wrap the blocks of your code into different closures. The main advantage of doing this is that you can use defer to call cancel()
which might be preferable if there are a lot of branches where you would otherwise have to call cancel()
explicitly.
Depending on your preference you can deal with any returned errors outside or inside the closure
func() {
ctx, cancel := contextWithTimeout(...)
defer cancel()
err := doSomethingA(ctx, ...)
if err != nil {
// handle error.
}
}()
err := func() error {
ctx, cancel := contextWithTimeout(...)
defer cancel()
return doSomethingB(ctx, ...)
}()
// Handle error of doSomethingB here.
This pattern is also useful for resources which need to be closed to avoid leaks like http response bodies, files and network connections.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论