Метод interval является упрощенным вариантом метода timer.

Подключение - import { interval } from ‘rxjs’;

Синтаксис - interval(period: number, scheduler: Scheduler): Observable

Пример кода:

const source = interval(1000);
source.subscribe(data => console.log(data));

… здесь в консоли появится серия 0,1,2,3 и тд - после задержки в одну секунду и затем с интервалом в одну секунду.


Ссылки:

Метод timer позволяет создавать удобную возможность выполнять что-либо через заданный промежуток времени.

Синтаксис - timer(delayTime, intervalTime).

Подключение - import { timer } from ‘rxjs’;

Пример кода:

const source = timer(1000, 1000);
source.subscribe(data => console.log(data));

Здесь - с задержкой в одну секунду (и с интервалом также в одну секунду) в консоли пойдут значения - 0, 1, 2, 3, 4 и тд. Если задержка не нужна, тогда можно поставить 0:

const source = timer(0, 1000);
source.subscribe(data => console.log(data));

Если нужно, чтобы timer сработал как метод setTimeout в классическом JavaScript, то нужно опустить второй аргумент - интервал выполнения:

const source = timer(1000);
source.subscribe(data => console.log(data));

… в этом случае команда выполнится один раз - в задержкой в одну секунду.

Маленький практический пример использования timer:

const source = timer(0, 1000);
source.subscribe(data => console.log(new Date()));

… это получился простейший таймер (не обратного отсчета). При использовании в Angular можно задействовать встроенный pipe - date: ‘hh:mm:ss’.

Интересная особенность - первым параметром можно задать дату запуска таймера - signature: timer(initialDelay: number | Date, period: number, scheduler: Scheduler): Observable. Не пробовал, но надо взять на заметку.

На timer очень похож метод interval, однако timer можно рассматривать как расширенный и более гибкий вариант interval.


Ссылки:

Git Stash

Я прямо влюбился в команду stash от git

Команда git stash предназначена для того, чтобы поместить текущие изменения в отдельное хранилище и вернуть файлы к исходному состоянию. То есть git stash прячет изменения в файлах и сохраняет эти изменения отдельно, чтобы потом можно было их вернуть.

Сохранение изменений

git stash save "description of stash"

… создать stash с человекопонятным описанием этого stash - чтобы можно было через день, глядя на него, догадаться вообще, что это такое и зачем оно делалось.

git stash -u save "description of stash"

… создать stash с изменениями, которые еще unstaged. Иначе они просто не попадут в снимок stash.

git stash branch newAwesomeBranch

… создание новой ветки из stash@{0}. Важный момент - чтобы изменения попали с новую ветку, они должны сначала быть помещены в stash@{0}.

git stash branch newAwesomeBranch stash@{1}

… поместить изменения из конктерного stash@{1} в новую ветку newAwesomeBranch.

git stash -p

… выборочное сохранение измененых файлов. Запускается пошаговый мастер, который будет последовательно спрашивать - помещать измененый файл в stash или нет.

Показ сохраненных изменений

git stash show

… показать, какие файлы изменены. Краткая справка, которая просто показывает, где были изменения и в каких файлах.

git stash show stash@{1}

… показать краткие изменения в конкретном stash.

git stash show -p stash@{1}

… показать изменения в файле. Можно увидеть в файле, что было добавлено или удалено.

git stash list

… показать список всех снимков stash. Причем, снимок с номером stash@{0} - это самый последний по времени снимок stash. Дальше - понарастающей - чем больше номер, тем раньше по времени он был сделан.

Удаление сохраненных изменений

git stash drop stash@{1}

… удалить определенный снимок stash@{1}.

git stash drop

… удалить последний снимок stash@{0}.

git stash clear

… удалить все изменения stash.

Применение сохраненных изменений

git stash apply

… применить последний по времени снимок stash.

git stash apply stash@{2}

… применить конкретный снимок stash.

git stash pop

… сокрещение от двух команд - apply и drop - применяет и автоматически удаляет после применения последний снимок stash - stash@{0}.

git stash pop stash@{2}

… сокрещение от двух команд - apply и drop - применяет и автоматически удаляет после применения конкретный снимок stash - stash@{2}.

Шаблон раннего возврата (return early pattern) в JavaScript - это простой способ уменьшить число else-операторов в теле функции до нуля. Есть много причин, чтобы предпочесть этот шаблон использованию else-операторов.

  • Уменьшение общего количества кода на странице
  • Уменьшение длины строк кода упрощением логической сложности
  • Улучшение удобочитаемости кода

Суть шаблона раннего возврата (return early pattern) заключается в том, чтобы заменить необходимость дополнительных условий в функциях JavaScript, используя ключевое слово return в теле оператора if.

Создадим функцию, которая ведет себя по-разному при определенных условиях (примечание: это тривиальный и надуманный пример, просто чтобы получить представление о сути вопроса):

function willItBlend (someObject) {
var ItWillBlend;

if (someObject.blendable === 'It will blend') {
itWillBlend = true;
} else {
itWillBlend = false;
}

return itWillBlend;
}

Хотя данная функция кажется читаемой, добавим в нее еще одно условие для проверки того, что функция вызывается для работы с объектом вместо undefined:

function willItBlend(someObject) {
var itWillBlend;

if (typeof someObject === 'object') {
if (someObject.blendable === 'It will blend') {
itWillBlend = true;
} else {
itWillBlend = false;
}
} else {
itWillBlend = false;
}

return itWillBlend;
}

Эта функция понятной и ее имя является описательным, однако она представляется все-же излишне сложной. Можем ли мы использовать шаблон раннего возврата (return early pattern) для повышения удобочитаемости и уменьшения количества else-выражений?

Попробуем:

function willItBlend(someObject) {
if (typeof someObject !== 'object') {
return false;
}

if (someObject.blendable !== 'It will blend') {
return false;
}

return true;
}

Используя шаблон раннего возврата (return early pattern), мы смогли удалить все ненужные else-инструкции и сделать функцию намного яснее и более краткой.

Бонус: одно условное выражение

Мы можем дополнительно переписать функцию для использования только одного оператора if.

Проверим:

function willItBlend(someObject) {
if (
typeof someObject !== 'object' ||
someObject.blendable !== 'It will blend'
) {
return false;
}

return true;
}

Метод call

Метод call и apply достаточно древние - они оба из стандарта ES3. Суть создания и работы методов - заставить некоторую произвольную функцию работать на каком-то объекте. Точнее - использовать контекст этого объекта.

Чтобы было понятнее, начнем с примера. Есть функция, которая работает таким образом:

function getName() {
  const name = this.name
  console.log(name)
}

Что будет, если вызвать эту функцию таким образом?

getName()

Сложный вопрос, так как мы видим, что в теле функции используется ключевое слово this. Это - ссылка на текущий объект и на свойство name этого объекта. Что это за объект? Неизвестно. Все будет зависеть от того, где будет вызвана функция getName() на исполнение. Допустим, если вызвать функцию в консоли браузера, то парсер обратиться к глобальному объекту window и попробует найти у него свойство name. В итоге мы получим undefined, так как вряд ли у объекта window есть свойство name.

При помощи метода call можно “привязать” функцию getName() к любому объекту. Другими словами - привязать контекст функции getName() к контексту объекта. Как?

Допустим, у нас есть объект:

const user1 = {
  name: 'Ivan',
  position: 'frontent developer',
  salary: 1200
}

Мы сделаем так:

const result1 = getName.call(user1)

Что будет происходить здесь? В этом случае ключевое слово this (в теле функции getName) будет указывать на объект user1, у которого есть свойство name. Как результат - в константе result1 будет находиться значение Ivan.

Если создадим еще один объект:

const user2 = {
  name: 'Joshua',
  position: 'ui designer',
  salary: 2200
}

И на нем вызовем функцию getName():

const result2 = getName.call(user2)

Что будет? В этом случае функция getName будет ссылаться уже на объект user2! И в константе result2 уже будет значение свойства name объекта user2 - Joshua.

call - более сложный вариант

Рассмотрим более сложный случай - когда функция принимает аргумент(ы). Допустим, такая функция,

function promote(position, salary) {
  this.salary = salary
  this.position = position
  return this.position + ' earns ' + this.salary + ' dollars'
}

И есть два объекта:

const junior = {
  name: 'Fritz',
  position: 'junior developer',
  salary: 1000
}
const middle = {
  name: 'Max',
  position: 'middle developer',
  salary: 2000
}
const senior = {
  name: 'Manu',
  position: 'senior developer',
  salary: 3000
}

Вызовем функцию promote() на каждом из объектов:

const result1 = promote.call(junior, 'super junior developer', 1200)
const result2 = promote.call(middle, 'super middle developer', 2200)
const result3 = promote.call(senior, 'super senior developer', 3200)

Что здесь произойдет? При каждом вызове функции promote() у нее будет разный контекст выполнения - объект junior, middle или senior. И обращаться функция promote() будет каждый раз к свойствам разных объектов - junior, middle или senior. Соответственно, результат тоже будет разным:

super junior developer earns 1200 dollars
super middle developer earns 2200 dollars
super senior developer earns 3200 dollars

Метод apply

Метод apply очень похож на метод call, за одним исключением. Аргументы метод apply принимает в виде массива, а не в виде списка, как метод call.

Проиллюстрируем пример - переделаем вызов функции promote() при помощи метода apply:

const resultA = promote.apply(junior, [ 'super junior developer', 1200 ])
const resultB = promote.apply(middle, [ 'super middle developer', 2200 ])
const resultC = promote.apply(senior, [ 'super senior developer', 3200 ])

Видим, что аргументы передаются в виде массива, но результат будет тот же. Как часто упоминается в различных туториалах, это сделано для того, чтобы передать неограниченное и заранее неизвестное количество аргументов.

Метод bind

Этот метод похож на предыдущие два - call и apply. Однако, у него есть два отличия - этот метод появился в стандарте ES5; и второе отличие - этот метод позволяет выполнить отложенный вызов функции.

То есть - метод call или apply вызываются на исполнение сразу, и результат их работы мы получаем сразу. С методом bind немного иначе:

const resultAA = promote.bind(junior)
const resultBB = promote.bind(middle)
const resultCC = promote.bind(senior)

Что мы сдесь сделали? Мы вызвали функции promote() и передали ей контекст выполнения; результат - экземпляр функции promote() с уже встроенным контекстом выполнения; экземпляр помещен в константу resultAA, resultBB или resultCC. Другими словами - это готовые функции с контекстом.

Осталось вызвать любую из них и передать ей аргументы, которые она ожидает:

const resultAAA = resultAA('super junior developer', 1200)
const resultBBB = resultBB('super middle developer', 2200)
const resultCCC = resultCC('super senior developer', 3200)

Получим результат:

super junior developer earns 1200 dollars
super middle developer earns 2200 dollars
super senior developer earns 3200 dollars

Видим - мы получили отложенный вызов каждой из функций.