It's been a while since I did much Go, but I think you can handle this cleanly by making one channel per task, and having an array of channels similar to the array of promises. Each channel takes that task's result, then closes. The caller waits on each channel in sequence.