Clojure, как создать вектор из элементов, поступающих в агрегатор core.async
Я следовал здесь и получаю вещи, называемые сегментами, поступающими в агрегатор. Все эти сегменты прибывают, и я могу распечатать их по мере их поступления. Но я хочу сделать из них неизменную структуру данных (вектор) по мере их поступления. Или даже подождать, пока они все прибудут, а затем сделать вектор. Я смогу узнать, когда прибыл последний, и отсортировать их. Мне необходимо conj
прибывающий сегмент к существующему до сих пор застроенному вектору. Я привык создавать такие векторы, используя возвраты из вызовов функций, но я не вижу, как эта возможность доступна для меня в потоке или блоке go.
2 ответа
Предположительно, поскольку вы можете получать несколько элементов, ваш асинхронный код уже находится в цикле.
Чтобы создать вектор из элементов, которые вы получаете, вы должны использовать привязку цикла.
(def acc-chan
(>/go-loop [accumulator []]
(let [item (>/<! source-chan)]
(if (nil? item)
accumulator
(recur (conj accumulator item)))))
go-loop
Вызов call немедленно вернет acc-chan, который получит возвращаемое значение цикла (аккумулятор) при выходе из цикла. Аккумулятор перепривязывается на каждой итерации цикла, добавляя еще один элемент в конец. Когда источник закрыт, аккумулятор возвращается из цикла и помещается на acc-chan
где вы можете прочитать его и использовать значение.
Другой вариант заключается в использовании (clojure.core.async/into [] source-chan)
, Как и другие "reducer-chans" в асинхронном инструментарии, он также основан на предположении, что вы будете close!
исходный канал, когда вы будете готовы получить результат.