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! исходный канал, когда вы будете готовы получить результат.

Другие вопросы по тегам