Фото Майк Алонзо на Бессмысленно
Трубопроводы с использованием 5 различных методов, тока и будущего.
Мы рефикторуем два куска кода, поднятыми из Трубопровод TC39 :
i) «Побочный эффект» кусок
const envarString = Object.keys(envars)
.map(envar => `${envar}=${envars[envar]}`)
.join(' ')
const consoleText = `$ ${envarString}`
const coloredConsoleText = chalk.dim(consoleText, 'node', args.join(' '))
console.log(coloredConsoleText)
II) “Чистый” кусок
const keys = Object.keys(values) const uniqueKeys = Array.from(new Set(keys)) const items = uniqueKeys.map(item =>
- {items}
Каждый имеет «цепочку» операций, используемых один за другим против предыдущего значения.
Первый кусок журналы Окончательное значение, второй возвращается Это:
- Оранжеры > Оранжездание > Councoletext > Окрашенные ConsonsOletext > журнал
- ценности > ключи > Уникальныеки > предметы > Неупорядочить список > возврат
В обоих случаях окончательное значение – единственное, что мы действительно заинтересованы, так что это делает их кандидатами на трубопровод!
Давайте начнем с…
i) Кусок «побочный эффект»
1. Используя пусть TMP.
Самый простой способ отказаться от этих временных переменных – объявить смешную Пусть TMP И постоянно переназначить его:
let tmp = envars
tmp = Object.keys(tmp)
tmp = tmp.map(envar => `${envar}=${envars[envar]}`)
tmp = tmp.join(' ')
tmp = `$ ${tmp}`
tmp = chalk.dim(tmp, 'node', args.join(' '))
console.log(tmp)
Это будет работать, но, возможно, есть менее подверженные ошибкам способы достижения того же самого. Кроме того, мусорные переменные в наши дни не совсем мода. 🤔
2. Использование обещания
Мы можем использовать Обещание и последовательность тогда чтобы сохранить Область каждой временной переменной под контролем:
Promise.resolve(envars)
.then(_ => Object.keys(_))
.then(_ => _.map(envar => `${envar}=${envars[envar]}`))
.then(_ => _.join(' '))
.then(_ => `$ ${_}`)
.then(_ => chalk.dim(_, 'node', args.join(' ')))
.then(_ => console.log(_))
Нет загрязнения приложений с TMP здесь! A Обещание несет идею «трубопроводов» от Оранжеры Всю подход для регистрации окончательного выхода Coloureated без перезаписи временную переменную.
Не совсем как мы обычно используем Обещание Возможно, но так как многие из нас знакомы с тем, как они объединяют вместе, это полезная выключающая точка для понимания трубопроводов для тех, которые не уже знакомы.
Кстати, мы могли бы использовать Объект. Keys. и console.log первый класс:
Promise.resolve(envars) .then(Object.keys) // instead of: _ => Object.keys(_) .then(console.log) // instead of: _ => console.log(_)
Но я избегаю использования этого стиля «молчаливого».
Я также намеренно избегаю:
Promise.resolve(
Object.keys(envars)
.map(envar => `${envar}=${envars[envar]}`)
.join(' ')
)
.then(_ => `$ ${_}`)
.then(_ => chalk.dim(_, 'node', args.join(' ')))
.then(console.log)
Вместо этого я постараюсь сохранить первый уровень отступов, как я думаю, это помогает передать полную конвейерную операцию немного лучше.
Во всяком случае, используя Обещание не идеален, если мы хотим Синхронный побочный эффект.
Выскакивать ждать Перед всей цепочкой возможна, конечно, но только если трубопровод сидит внутри async Функция сама, что может быть не то, что мы хотим.
Итак, давайте попробуем некоторые методы синхронных трубопроводов!
3. Использование трубы ()
С этим волшебным заклинанием:
function pipe(x, ...fns) {
return fns.reduce((g, f) => f(g), x)
}
…мы можем иметь:
pipe(
envars,
_ => Object.keys(_),
_ => _.map(envar => `${envar}=${envars[envar]}`),
_ => _.join(' '),
_ => `$ ${_}`,
_ => chalk.dim(_, 'node', args.join(' ')),
_ => console.log(_)
)
Мы упали все эти .then () и оставил лямбдас (стрелка-функции) позади аргументов к труба которые будут работать в последовательности, с первым аргументом, обеспечивающим начальное значение первым лямбда .
Удобное!
4. Используя хак-трубы
Если вы используете Бабел или жить в будущем, где Трубопровод TC39 приземлился, вы можете использовать хак-трубы:
envars
|> Object.keys(^)
|> ^.map(envar => `${envar}=${envars[envar]}`)
|> ^.join(' ')
|> `$ ${^}`
|> chalk.dim(^, 'node', args.join(' '))
|> console.log(^)
Дщаться! И Начиная выглядеть как фактическое труба Слева там нет?
Обратите внимание, что токен ^ Выступает в качестве переменной «предыдущего значения», когда мы используем |> , как когда мы использовали _ или TMP. ранее.
5. Использование функтора идентификатора
Давайте бросим еще одно магическое заклинание:
const Box = x => ({
map: f => Box(f(x))
})
… и сделать трубопровод с этим:
Box(envars)
.map(_ => Object.keys(_))
.map(_ => _.map(envar => `${envar}=${envars[envar]}`))
.map(_ => _.join(' '))
.map(_ => `$ ${_}`)
.map(_ => chalk.dim(_, 'node', args.join(' ')))
.map(_ => console.log(_))
Выглядит подозрительно, как Обещание Трубопровод, кроме тогда заменяется на карта Отказ 🤔
Так что это 5 различных методов трубопроводов! Мы будем применять их сейчас в обратном порядке для …
II) «Чистый» кусок
Вот ссылочный код снова в качестве напоминания:
const keys = Object.keys(values) const uniqueKeys = Array.from(new Set(keys)) const items = uniqueKeys.map(item =>
- {items}
Для начала мы сначала сделаем Коробка монад:
const Box = x => ({
map: f => Box(f(x)),
chain: f => f(x) // there we go
})
Добавляя цепь Мы можем вернуть JSX в конце конвейера, не превращая его в еще один Коробка (который на самом деле не имеет значения в кусок побочных эффектов, так как мы ничего не возвращали):
return Box(values) .map(_ => Object.keys(_)) .map(_ => Array.from(new Set(_))) .map(_ => _.map(item =>
- {_}
Рода чувствует себя как Обещание Трубопровод, если у него был ждать В начале, а? Вместо этого это Коробка с цепь в конце. 🤔
И синхронно тоже, как труба () Действительно
Говоря о которой, давайте вернемся и используем его сейчас:
Использование трубы ()
return pipe( values, _ => Object.keys(_), _ => Array.from(new Set(_)), _ => _.map(item =>
- {_}
Довольно похоже на кусок побочных эффектов, кроме как выявить, что да, труба действительно вернутся нам стоимость, возвращенная последними лямбда в цепочке. (Это прекрасно в этом случае.)
Использование обещания
Вернуться на землю Async, имеет ли смысл вернуться JSX от Обещание ? Я оставлю морали этого до вас, но вот в любом случае:
return await Promise.resolve(values) .then(_ => Object.keys(_)) .then(_ => Array.from(new Set(_))) .then(_ => _.map(item =>
- {_}
( ждать бросил – просто для общения намерения, но это не требуется.)
Наконец, давайте вернемся прямо к Пусть TMP :
Используя пусть TMP.
let tmp = values tmp = Object.keys(tmp) tmp = Array.from(new Set(tmp)) tmp = tmp.map(item =>
- {tmp}
И вот где мы пришли!
Вывод
Все во всем, что мы охватывали 5 разных способов трубопроводы : Способ преобразования одного значения в другое в последовательности шагов, не беспокоясь о том, что позвонить в биты между ними.
Пусть TMP.Обещать # тогдаТруба (стартовая канала, ... сквозь этифункции)- Взломать
|>Трубы (^) Функтор идентификатора/Монад(Коробка # карта/цепочка)
Если вы узнали что-то новое или иметь что-то, чтобы последовать, пожалуйста, оставьте комментарий ниже. В любом случае, спасибо за чтение!
Оригинал: “https://dev.to/shuckster/pipelines-in-javascript-1633”