Я понимаю, что «блоки перехода» (будь то go
или go-loop
или, возможно, другие конструкции) возвращают канал. Однако я никогда не понимал предназначения этого канала. Я хотел бы знать, как его использовать. Возможно, я создаю дополнительные каналы, когда мне это не нужно.
Почему блоки core.async go возвращают канал?
Ответы (1)
Я использую канал возврата блока go
как дескриптор, который я могу передать другой функции (не только макросу), которая хочет синхронизироваться с завершением блока go
. В качестве альтернативы я могу выполнить блокировку чтения на канале, чтобы гарантировать завершение выполнения go
-блока.
Вот простой пример (не предназначенный для использования в каком-либо производственном коде для вычисления суммы), который выполняет двустороннее распараллеливание:
(defn par-sum [coll]
(let [half-n (/ (count coll) 2)
[left right] (split-at half-n coll)
left-sum-chan (async/go (core/reduce + 0 left))
right-sum (core/reduce + 0 right)
left-sum (async/<!! left-sum-chan)]
(+ left-sum right-sum)))
В этом примере мы вычисляем левую и правую суммы параллельно. Поскольку нам нужна левая сумма для вычисления общей суммы, мы должны дождаться результата и получить результат блока go
.
person
shams
schedule
31.03.2016
Так как это блок go, нет такого понятия, как возвращаемое значение, которое могло бы быть для функции. Чтобы обойти это, блок go возвращает канал, в который он отправляет возвращаемое значение.
- person Chris Murphy; 01.04.2016