В моем последнем блоге я затронул вопросы синхронизации асинхронных задач. Я уверен, что вы также читали последний раздел, где я упомянул PromiseKit и AwaitKit. Как уже упоминалось, у меня есть сомнения по поводу PromiseKit, хотя мне очень нравятся обещания и особенно Awaits!

Await попал в Javascript с ES8 в прошлом году и упростил проблему из вышеупомянутой статьи. Я был в некотором роде вдохновлен Yannick’s AwaitKit и думал, могу ли я сделать что-то подобное, чтобы инкапсулировать шаблон семафора и сделать его более тривиальным. Я должен признать, что я не особо поклонник сахарного синтаксиса и обфускации совершенно корректных функций стандартного языка / SDK / Framework, поэтому на этот раз я больше хотел поиграть с ним и подумал, смогу ли я превратить это во что-нибудь, что бы быть приемлемым также для разработчиков, у которых есть некоторые предубеждения по поводу прямого использования семафоров или других парадигм.

3 Асинхронные задачи с семафорами

У нас есть 3 асинхронные задачи, которые мы хотим выполнять зависимым образом:

Результат sum используется как параметр в sumAndDifference, а результаты последнего используются в sumAndDifferenceAndMultiplication. Согласно вышеупомянутому блогу, эту проблему можно было бы легко решить без такого «ада закрытия»:

Если мы заглянем в код, консоль должна распечатать это: 3, 6, 0, 6, 6, 0.

Кортежи?

Как насчет того, чтобы код сверху выглядел примерно так:

Итак, мы просто передаем наш вызов как функцию и получаем результат в виде async.await.... Но что мы здесь имеем ?? 😱 Кортежи ?? 😮😮 Конечно, а почему бы и нет? Похоже, мы инкапсулировали всю «сложность» семафоров, а параметры обратного вызова волшебным образом превратились в кортежи.

Вся «магия» исходит отсюда, от двух очень коротких функций, которые не затрагивают логику, просто помещают семафоры и «переводят» обратный вызов в кортеж:

Я уверен, вы легко можете себе представить, как эти две функции реализованы одинаково для 1 и 2 параметров обратного вызова, верно?

Тем не менее, похоже, что здесь можно было бы внести множество улучшений. да. Я попытался с вариативными параметрами сделать только эти 2 функции для любого количества параметров обратного вызова, но, к сожалению (или логически), у вас не может быть нефиксированного количества параметров кортежа при компиляции время.

Я также пытался реализовать все с помощью универсальных шаблонов, однако в некотором смысле, как я хотел, чтобы это использовалось, Swift не может определить тип, и компилятор выдает ошибку.
В конце , Мне пришлось довольствоваться довольно хорошей идеей внедрения закрытия обратного вызова, по одному для каждого определенного количества параметров. Что на самом деле не так уж и плохо. Сколько вы обычно получаете от обратного звонка? 1, 2, 3? Более? Ну вот! ;)

Этот внедренный обратный вызов никогда не ссылается на параметры обратного вызова, равно как и функция ожидания никогда не ссылается на параметры и их типы. Он обрабатывает только семафоры. Однако, не касаясь их, компилятор не может вывести тип, поэтому нам нужно понижать, когда мы используем результат.

Вывод

Не совсем мой любимый подход, поскольку у меня нет проблем с чтением и пониманием стандартного кода, но если мне не нужно использовать сложные сторонние библиотеки / фреймворки, и мой «сахарный» вспомогательный объект будет коротким и простым, как этот, тогда я мог бы даже пойти на это сам.

Если у вас есть идеи, как это улучшить, скачайте, пожалуйста, образец и поиграйте с ним.