Translate

Поиск по этому блогу

Показаны сообщения с ярлыком Web. Показать все сообщения
Показаны сообщения с ярлыком Web. Показать все сообщения

четверг, 10 мая 2018 г.

Интервью JavaScript: Что такое Promise?

«Мастер интервью с JavaScript» представляет собой серию сообщений, предназначенных для подготовки кандидатов на общие вопросы, с которыми они могут столкнуться при подаче заявки на позицию JavaScript на среднем и старшем уровнях (a mid to senior-level JavaScript position). Это вопросы, которые я часто использую в реальных интервью.




Что такое Promise?

Обещание (Promise)- это объект, который может произвести одно значение в будущем: либо разрешенное значение, либо причина, по которой он не разрешен (например, произошла сетевая ошибка).

Обещание может быть в одном из трех возможных состояний: выполнено- fulfilled, отклонено - rejected или ожидается- pending. Пользователи Promise могут присоединять обратные вызовы для обработки выполненного значения или причины отклонения.

Обещания нетерпеливы, а это означает, что обещание начнет выполнять любую задачу, которую вы даете ему, как только вызывается конструктор обещаний. Если вам нужно лениться, проверьте observables или tasks.

Неполная история Promise - обещаний

Раннее, реализации обещаний и фьючерсов (аналогичная / смежная идея) начали появляться в таких языках, как MultiLisp и Concurrent Prolog еще в 1980-х годах. Использование слова Promise - «обещание» было придумано Барбарой Лисковой и Любой Шририа в 1988 году.

В первый раз, когда я услышал о обещаниях в JavaScript, Node был совершенно новым, и сообщество обсуждало лучший способ обработки асинхронного поведения. Сообщество какое-то время экспериментировало с обещаниями, но в конечном итоге решилось на Node-standard error-first callbacks (стандарт Ноды с ошибкой первого обратного вызова).

Примерно в то же время Dojo добавили обещания через Deferred API. Растущий интерес и активность в конечном итоге привели к недавно сформированной спецификации Promises / A, призванной сделать различные обещания более интероперабельными.

Асинхронное поведение jQuery было реорганизовано вокруг обещаний (Promise). Поддержка обещаний (Promise) jQuery имела большое сходство с Dojo's Deferred, и она быстро стала наиболее часто используемой реализацией (Promise) обещаний в JavaScript из-за огромной популярности jQuery - на то время. Однако, там не было поддержки двухканального (выполненное / отклоненное) поведения цепочки и управления исключениями, на которое люди рассчитывали при создании инструментов поверх обещаний (Promise).

Несмотря на эти недостатки, jQuery официально сделал JavaScript обещания (Promise) мейнстримом, и лучше автономные библиотеки обещаний, таких как Q, When, и Bluebird стали очень популярными. Несовместимость реализации jQuery привела к некоторым важным разъяснениям в спецификации обещаний, которая была переписана и переименована как спецификация Promises / A +.

ES6 принесла Promise / A + совместимый глобальный Promise, и некоторые очень важные API были построены поверх новой стандартной поддержки Promise: особенно спецификация WHATWG Fetch (ссылка заблокирована в России-> use VPN - пр. переводчика) и стандарт Async Functions (проект на 3 стадии на момент написания этой статьи).

Promises - обещаний, описанные здесь, это промисы которые совместимы с спецификациями Promises / A +, с акцентом на стандартную реализацию Promise ECMAScript.

Как работают promis?

Обещание (promis)- это объект, который можно синхронно возвращать из асинхронной функции. Он будет в одном из трех возможных состояний:

  1. Fulfilled(выполнено): onFulfilled() будет вызвано (например: reject() был вызван)
  2. Rejected (отклонено): onRejected() будет вызвано (например: reject() был вызван)
  3. Pending (ожидает): еще не выполнено или отклонено.


Обещание (promis) разрешается - settled, если оно не ожидается (оно было разрешено или отклонено - resolved or rejected). Иногда люди используют resolved и settled как то же самое: not pending..

После settled обещание не может быть resettled. Вызов resolve () или reject () снова не будет иметь эффекта. Важнейшей особенностью является неизменность обещанного обещания (promis).

Собственные обещания JavaScript не раскрывают состояния обещаний. Вместо этого вы должны рассматривать обещание как черный ящик. Только функция, ответственная за создание обещания, будет обладать знанием статуса обещания (promise status) или доступа к разрешению или отказу (resolve or reject).

Вот функция, которая возвращает обещание, которое будет разрешено после заданной задержки:

const wait = time => new Promise((resolve) => setTimeout(resolve, time));

wait(3000).then(() => console.log('Hello!')); // 'Hello!'


Пример кода на CodePen

Наш вызов wait (3000) будет ждать 3000 мс (3 секунды), а затем выведет в консоль «Hello!». Все спецификации, совместимые с обещаниями, определяют метод .then (), который вы используете для передачи обработчиков, которые могут принимать разрешенные или отклоненные значения.

Конструктор обещаний ES6 выполняет функцию. Эта функция принимает два параметра: resolve () и reject (). В приведенном выше примере мы используем только метод resolve (), поэтому я оставил reject () в списке параметров. Затем мы вызываем setTimeout () для создания задержки и вызываем resolve (), когда время ожидания закончено.

Вы можете опционально resolve () или reject () со значениями, которые будут переданы на функции обратного вызова, связанные с .then ().

Когда я отклоняю reject () со значением, я всегда передаю объект Error. Обычно я хочу два возможных состояния разрешения: нормальный счастливый путь или исключение - все, что останавливает нормальный - удачный путь. Передача объекта Error делает это явным.

Важные правила обещания (promise)

Стандарт для обещаний был определен сообществом Promises / A + Существует множество реализаций, которые соответствуют стандарту, включая общие требования стандарта ECMAScript для JavaScript.

Обещания следующей спецификации должны соответствовать определенному набору правил:
  1. Обещание или «thenable» - это объект, который поставляет стандартный метод .then ().
  2. Ожидающее обещание (pending promise) может перейти в отработанное (fulfilled) или отвергнутое (rejected) состояние.
  3. уже установленное состояние fulfilled - исполненное или rejected - отвергнутое. не должно и не может меняться. переходить в другие состояния.
  4. Однажды установленное состоянеи должно иметь значение ( оно может быть и undefined). Это значение не должно меняться.
Изменение в этом контексте относится к сравнению идентичности (===). Объект может использоваться как выполненное значение, а свойства объекта могут мутировать.

Каждое обещание должно предоставить метод .then () со следующей подписью:

promise.then(
  onFulfilled?: Function,
  onRejected?: Function
) => Promise



Метод .then () должен соответствовать следующим правилам:
  1. И onFulfilled (), и onRejected () являются необязательными.
  2. Если предоставленные аргументы не являются функциями, они должны быть проигнорированы.
  3. onFulfilled () будет вызван после того, как обещание будет исполнено, причем значение обещания станет первым аргументом.
  4. onRejected () будет вызываться после того, как обещание будет отклонено, и причина отказа в качестве первого аргумента. Причиной может быть любое допустимое значение JavaScript, но поскольку отклонения по существу являются синонимом исключений, я рекомендую использовать объекты Error.
  5. Ни onFulfilled (), ни onRejected () не могут быть вызваны более одного раза.
  6. .then () можно вызвать много раз по тому же обещанию. Другими словами, обещание может быть использовано для агрегирования обратных вы
  7. .then () должен вернуть новое обещание, promise2.
  8. Если onFulfilled () или onRejected () возвращают значение x, а x является обещанием, promise2 будет блокироваться (предполагать то же состояние и значение, что и x). В противном случае promise2 будет выполнено со значением x.
  9. Если либо onFulfilled, либо onRejected выбрасывает исключение e, promise2 должен быть rejected (отклонен) вместе с e в качестве причины.
  10. Если onFulfilled не является функцией и promise1 выполняется, promise2 должно выполняться с тем же значением, что и promise1.
  11. Если onRejected не является функцией и promise1 отвергается- rejected, promise2 должен быть отклонен по той же причине, что и promise1.


Цепочка обещаний

Именно потому, что .then () всегда возвращает новое обещание, можно связать обещания с точным контролем над тем, как и где обрабатываются ошибки. Обещания позволяют вам имитировать поведение обычного / синхронного кода try / catch.

Подобно синхронному коду, цепочка приведет к последовательности, которая выполняется в последовательном порядке. Другими словами, вы можете сделать:

fetch(url)
  .then(process)
  .then(save)
  .catch(handleErrors)
;



Предполагая, что каждая из функций, fetch (), process () и save () возвращают обещания, process () будет ждать завершения функции fetch () перед запуском, а save () будет ждать завершения process () перед запуском. handleErrors () будет работать только в том случае, если любое из предыдущих обещаний отклоняется.

Вот пример сложной цепочки обещаний с множественными отказами:

const wait = time => new Promise(
  res => setTimeout(() => res(), time)
);

wait(200)
  // onFulfilled() can return a new promise, `x`
  .then(() => new Promise(res => res('foo')))
  // the next promise will assume the state of `x`
  .then(a => a)
  // Above we returned the unwrapped value of `x`
  // so `.then()` above returns a fulfilled promise
  // with that value:
  .then(b => console.log(b)) // 'foo'
  // Note that `null` is a valid promise value:
  .then(() => null)
  .then(c => console.log(c)) // null
  // The following error is not reported yet:
  .then(() => {throw new Error('foo');})
  // Instead, the returned promise is rejected
  // with the error as the reason:
  .then(
    // Nothing is logged here due to the error above:
    d => console.log(`d: ${ d }`),
    // Now we handle the error (rejection reason)
    e => console.log(e)) // [Error: foo]
  // With the previous exception handled, we can continue:
  .then(f => console.log(`f: ${ f }`)) // f: undefined
  // The following doesn't log. e was already handled,
  // so this handler doesn't get called:
  .catch(e => console.log(e))
  .then(() => { throw new Error('bar'); })
  // When a promise is rejected, success handlers get skipped.
  // Nothing logs here because of the 'bar' exception:
  .then(g => console.log(`g: ${ g }`))
  .catch(h => console.log(h)) // [Error: bar]
;


Посмотреть на Codepen

Обработка ошибок

Обратите внимание, что обещания имеют как успешное завершение, так и обработчик ошибок, и очень часто можно увидеть код, который делает это:

save().then(
  handleSuccess,
  handleError
);



Но что произойдет, если handleSuccess () выдает ошибку? Обещание, возвращенное из .then (), будет отклонено, но нет ничего, чтобы поймать отказ - это означает, что ошибка в вашем приложении проглатывается. К сожалению!

По этой причине некоторые люди считают, что приведенный выше код является анти-шаблоном, и вместо этого рекомендуют следующее:


save()
  .then(handleSuccess)
  .catch(handleError)
;



Разница тонкая, но важная. В первом примере ошибка, возникающая в операции save (), будет обнаружена, но ошибка, возникающая в функции handleSuccess (), будет проглатываться.


Без .catch () ошибка в обработчике успеха не реализована.
Во втором примере .catch () будет обрабатывать отклонения от save () или handleSuccess ().


С .catch () обрабатываются оба источника ошибок. (источник диаграммы)

Конечно, ошибка save () может быть сетевой ошибкой, тогда как ошибка handleSuccess () может быть вызвана тем, что разработчик забыл обработать определенный код состояния. Что делать, если вы хотите обращаться с ними по-другому? Вы можете выбрать для них обоих:

save()
  .then(
    handleSuccess,
    handleNetworkError
  )
  .catch(handleProgrammerError)
;



Независимо от того, что вы предпочитаете, я рекомендую прекратить все цепочки обещаний с помощью .catch (). Это стоит повторить:
I recommend ending all promise chains with a .catch().



Как отменить обещание?

Одна из первых вещей, которые новые пользователи часто спрашивают, - это как отменить обещание. Вот идея: просто отвергайте (reject) обещание с «Отменой» в качестве причины. Если вам нужно иметь дело с ним иначе, чем с «нормальной» ошибкой, выполните разветвление в обработчике ошибок.

Вот некоторые распространенные ошибки, которые люди совершают, когда откатываются от обещания:

Добавление .cancel () к обещанию

Добавление .cancel () делает обещание нестандартным, но оно также нарушает другое правило обещаний: только функция, которая создает обещание, должна иметь возможность разрешать, отклонять или отменять обещание. Выявление этого нарушает эту инкапсуляцию и побуждает людей писать код, который манипулирует обещанием в местах, которые не должны знать об этом. Избегайте "спагетти" и сломанных обещаний.

Забыли почистить.

367/5000 Некоторые умные люди поняли, что есть способ использовать Promise.race () как механизм отмены. Проблема заключается в том, что контроль отмены берется из функции, которая создает обещание, которое является единственным местом, где вы можете проводить правильные действия по очистке, такие как очистка тайм-аутов или освобождение памяти путем очистки ссылок на данные и т. д.

забыли обработать reject отклоненного обещания

Знаете ли вы, что Chrome бросает предупреждающие сообщения по всей консоли, когда вы забываете обработать отказ от обещаний? К сожалению!

Слишком сложно

Изъятое предложение TC39 об отмене предложило отдельный канал обмена сообщениями для отмены. Он также использовал новую концепцию, называемую токеном отмены. На мой взгляд, решение значительно раздуло бы обещание спецификации, и единственная особенность, которая могла бы обеспечить, что спекуляции не поддерживают напрямую, - это разделение отказов и аннулирования, что не является необходимым для начала.

Вы хотите переключиться в зависимости от того, есть ли исключение или отмена? Да, конечно. Это работа обещания? По-моему, нет, это не так.

Переосмысление отмены обещаний

Как правило, я передаю всю информацию, которую обещание необходимо определить, как разрешить / отклонить / отменить на время создания обещания. Таким образом, нет необходимости в методе .cancel () по обещанию. Возможно, вам будет интересно узнать, как вы могли бы узнать, собираетесь ли вы отменить время обещания.

«Если я еще не знаю, отменить или нет, как я узнаю, что передать, когда я создам обещание?»


Если бы существовал какой-то объект, который мог бы выдерживать потенциальную ценность в будущем ... о, подождите.

Значение, которое мы передаем, чтобы представлять, отменить или нет, может быть обещанием. Вот как это может выглядеть:


const wait = (
  time,
  cancel = Promise.reject()
) => new Promise((resolve, reject) => {
  const timer = setTimeout(resolve, time);
  const noop = () => {};

  cancel.then(() => {
    clearTimeout(timer);
    reject(new Error('Cancelled'));
  }, noop);
});

const shouldCancel = Promise.resolve(); // Yes, cancel
// const shouldCancel = Promise.reject(); // No cancel

wait(2000, shouldCancel).then(
  () => console.log('Hello!'),
  (e) => console.log(e) // [Error: Cancelled]
); 


Посмотреть на CodePen

Мы используем назначение параметров по умолчанию, чтобы сказать, что он не отменяет по умолчанию. Это делает параметр отмены cancel удобным дополнением. Затем мы устанавливаем таймаут, как и раньше, но на этот раз мы фиксируем идентификатор тайм-аута, чтобы мы могли его очистить позже.

Мы используем метод cancel.then () для обработки отмены и очистки ресурсов. Это будет выполняться только в том случае, если обещание будет отменено, прежде чем у него будет возможность его решить. Если вы отмените слишком поздно, вы упустили свой шанс. Этот поезд покинул станцию.

Примечание. Возможно, вам интересно, для чего предназначена функция noop (). Слово noop означает no-op, что означает функцию, которая ничего не делает. Без него V8 будет вызывать предупреждения: UnhandledPromiseRejectionWarning: Отказ от необработанного обещания. Это хорошая идея, чтобы всегда обрабатывать отклонения обещаний, даже если ваш обработчик является noop ().


Абстрагированное Отклонение обещаний

Это нормально для таймера wait (), но мы можем абстрагировать эту идею дальше, чтобы инкапсулировать все, что вам нужно запомнить:
  1. Отклонить обещание отмены по умолчанию - мы не хотим отменять или бросать ошибки, если не будет отменено обещание отмены.
  2. Не забудьте выполнить очистку, когда вы отклоняете для отмены.
  3. Помните, что очистка onCancel сама может выдать ошибку, и эта ошибка также потребует обработки. (Обратите внимание, что обработка ошибок в примере ожидания отсутствует - легко забыть!)


Давайте создадим отменяемую обещающую утилиту, которую вы можете использовать, чтобы обернуть любое обещание. Например, для обработки сетевых запросов и т. Д. Подпись будет выглядеть так:


speculation(fn: SpecFunction, shouldCancel: Promise) => Promise



Функция SpecFunction аналогична функции, которую вы передали бы в конструктор Promise, за одним исключением: для него используется обработчик onCancel ():


SpecFunction(resolve: Function, reject: Function, onCancel: Function) => Void






// HOF Wraps the native Promise API
// to add take a shouldCancel promise and add
// an onCancel() callback.
const speculation = (
  fn,
  cancel = Promise.reject() // Don't cancel by default
) => new Promise((resolve, reject) => {
  const noop = () => {};

  const onCancel = (
    handleCancel
  ) => cancel.then(
      handleCancel,
      // Ignore expected cancel rejections:
      noop
    )
    // handle onCancel errors
    .catch(e => reject(e))
  ;

  fn(resolve, reject, onCancel);
});


GitHub

Обратите внимание, что этот пример - всего лишь иллюстрация, чтобы дать вам суть того, как он работает. Есть и другие краевые случаи, которые нужно учитывать. Например, в этой версии handleCancel вызывается, если вы отмените обещание после того, как оно уже установлено.

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

Давайте используем улучшенную абстракцию библиотеки для перезаписи утилиты waitable () для отмены. Сначала установите спекуляцию:


   npm install --save speculation



Теперь вы можете импортировать и использовать это:


import speculation from 'speculation';

const wait = (
  time,
  cancel = Promise.reject() // By default, don't cancel
) => speculation((resolve, reject, onCancel) => {
  const timer = setTimeout(resolve, time);

  // Use onCancel to clean up any lingering resources
  // and then call reject(). You can pass a custom reason.
  onCancel(() => {
    clearTimeout(timer);
    reject(new Error('Cancelled'));
  });
}, cancel); // remember to pass in cancel!

wait(200, wait(500)).then(
  () => console.log('Hello!'),
  (e) => console.log(e)
); // 'Hello!'

wait(200, wait(50)).then(
  () => console.log('Hello!'),
  (e) => console.log(e)
); // [Error: Cancelled]


GitHub wait-speculation.js

Это немного упрощает, потому что вам не нужно беспокоиться о noop (), ловя ошибки в вашей функции onCancel (), функции или других случаях. Эти детали были отвлечены speculation (). Проверьте это и не стесняйтесь использовать его в реальных проектах.

Дополнительные возможности Native JS Promise

У родного объекта Promise есть некоторые дополнительные вещи, которые могут вас заинтересовать:
  • Promise.reject() - возвращает отклоненное обещание.
  • Promise.resolve() - возвращает разрешенное обещание.
  • Promise.race() - берет массив (или любой итерабельный) и возвращает обещание, которое разрешает со значением первого разрешенного обещания в итерируемом, или отклоняет по причине первого обещания, которое отвергается.
  • Promise.all() - берет массив (или любой итерабельный) и возвращает обещание, которое разрешает, когда все обещания в итерируемом аргументе разрешаются, или отклоняется по причине первого обещанного обещания, которое отклоняет.


Заключение

Обещания стали неотъемлемой частью нескольких идиом в JavaScript, включая стандарт WHATWG Fetch, используемый для большинства современных запросов ajax, и стандарт Async Functions, используемый для создания синхронного асинхронного кода.

Асинхронные функции - это этап 3 на момент написания этой статьи, но я предсказываю, что они скоро станут очень популярным, очень часто используемым решением для асинхронного программирования в JavaScript, а это значит, что научиться оценивать обещания будет еще более важным для JavaScript разработчиков в ближайшем будущем.

Например, если вы используете Redux, я предлагаю вам проверить redux-saga: библиотека, используемая для управления побочными эффектами в Redux, которая зависит от асинхронных функций в документации.

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

Исследуйте серию



Барбара Лисков; Люба Шрира (1988). «Обещания: лингвистическая поддержка эффективных асинхронных вызовов процедур в распределенных системах». Материалы конференции SIGPLAN '88 по программированию и внедрению языка программирования; Атланта, Джорджия, США, стр. 260-267. ISBN 0-89791-269-1, опубликованный ACM. Также опубликовано в ACM SIGPLAN Notices, том 23, выпуск 7, июль 1988 г.







Автор: Eric Elliott .
Перевод: Kolesnikov Yaroslav



                                                                                                                                                             

среда, 9 мая 2018 г.

React.js (2) Разбиваем на компоненты.

Хранить весь код в одном файле index.js неудобно и поэтому мы разобьем наш файл на компоненты.

Первая часть о том, как развернуть быстро и легко React приложение на локальном сервере находится здесь - React.js Настройка окружения.



Каждый компонент может быть повторно использован и представляет собой некую отдельную, самостоятельную часть (можно представить как строительный блок) кода. Будет правильным поместить их в отдельные файлы. Поэтому в папке src мы создадим для всех компонентов отдельную папку - components. В ней создадим два файла - Article.js и App.js.

В них мы поместим код (функцию) наших компонентов из файла index.js.

Затем, мы подключим к каждому файлу React, так как именно его переменная React участвует в строительстве приложения и выносить ее в глобальную область видимости является плохой практикой. Именно поэтому мы создадим к ней доступ в каждом файле наших компонентов.

Для этого мы пропишем строку import React from 'react' в самом начале файлов Article.js и App.js.

Теперь нам нужно произвести подключение наших компонентов. Для этого под функциями в файлах компонентов мы сделаем export наших компонентов. Например так:

export default App - для App - компонента.

export default Article - для Article - компонента.

В компонент App нам нужно импортировать код компонента Article, так как он принимает участие в строительстве самого App - компонента. вспоминаем:

function App() {
 return (
    <div>
        <h1>App Name</h1>
        <Article/>
    </div>
  );
}



Именно поэтому мы в фале App.js пишем - import Article from './Article'

После этих изменений стоит запустить сервер (в КС (bash) - npm start. см. Здесь! и убедиться, что все продолжает работать!

На данном этапе наш код компонента Article показывает статические названия, которые мы прописали внутри тегов title, body и т.д. Но нам нужно сделать таким образом, чтобы туда автоматически подставлялись текст, заголовок и прочие необходимые атрибуты статьи.

Для этого мы можем использовать js - переменные ( внутри фигурных скобок - { js-variable } ).

Наши компоненты (App и Article) это обычные функции и им в аргументы мы можем передавать нужные данные. Все данные будут приходить в первом аргументе и его принято называть props.

Коль скоро мы хотим получить в компоненте Article статью, то мы можем создать переменную const {article} = props - используем деструктуризацию объекта и все эти переменные мы сможем использовать внутри JSX.({ article.title }, { article.text } и пр.)

Файл Article.js

import React from 'react'

function Article(props) {
  const {article} = props
  const body = <section>{ article.text }</section> 
 return(
      <div>
        <h2>{ article.title }</h2> 
        { body }
        <h3>
         "creation date : "{ (new Date(article.date)).toDateString()}
        </h3>
      </div>
    );
}

export default Article



Файл App.js

import React from 'react'
import Article from './Article'

import articles from '../fixtures.js'

function App() {
 return (
    <div>
        <h1>App Name</h1>
        <Article article={articles[0]}/>
    </div>
  );
}

export default App



Здесь стоит пояснить, что строкой import articles from '../fixtures.js' мы подключаем файл в котором будут храниться сами статьи.

Для того, чтобы передать наши статьи article={articles[0]}
Файл fixtures.js

export default [
    {
        "id": "56c782f18990ecf954f6e027",
        "date": "2016-06-09T15:03:23.000Z",
        "title": "React Is Awesome!!!",
        "text": "React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes. \n We don't make assumptions about the rest of your technology stack, so you can develop new features in React without rewriting existing code. Build encapsulated components that manage their own state, then compose them to make complex UIs. Since component logic is written in JavaScript instead of templates, you can easily pass rich data through your app and keep state out of the DOM.",
        "comments": [
            {
                "id": "qwerqwer",
                "user": "Gilliam Underwood",
                "text": "Velit anim deserunt elit velit est fugiat duis eiusmod eu do incididunt ut tempor voluptate. Officia dolor aliqua id anim mollit pariatur id commodo. Laborum minim non ut aliquip commodo est consectetur. Mollit eu aliqua tempor est nulla ullamco irure. Sit non amet et eiusmod cillum ex cillum anim incididunt ad laboris mollit. Sunt quis incididunt elit ea qui non ullamco aliquip consequat voluptate eiusmod est. Irure laboris amet culpa sit aliquip."
            },
            {
                "id": "lkjhsdlfkg",
                "user": "Dolly Franklin",
                "text": "Aliquip id nostrud adipisicing irure. Labore reprehenderit ea ex officia ullamco incididunt consequat elit amet quis commodo. Fugiat amet veniam cillum ut aliquip velit est esse minim fugiat eiusmod sint. Commodo ea in culpa deserunt."
            },
            {
                "id": "zxcvzcxvzxcv",
                "user": "Brennan Atkins",
                "text": "Nisi sit nisi cillum dolor fugiat sint do nostrud ex cillum cupidatat. Culpa do duis non et excepteur labore dolor culpa qui tempor veniam. Ex labore deserunt qui sit aute ad incididunt do cupidatat eiusmod reprehenderit ad. Qui laborum qui voluptate velit et consectetur ipsum enim dolore minim. Est sint velit tempor reprehenderit. Qui consectetur ad minim consequat."
            },
            {
                "id": "fghjfghjfghj",
                "user": "Jodi Humphrey",
                "text": "Non amet amet ut magna culpa dolore consequat occaecat. Commodo adipisicing laboris voluptate enim mollit mollit anim aliquip deserunt nostrud deserunt cillum est. Ad eu cupidatat dolor nostrud et minim id in dolor occaecat ad magna elit. Laboris elit laboris aliquip Lorem reprehenderit id amet reprehenderit laborum minim incididunt cupidatat eiusmod."
            },
            {
                "id": "ertyoertywte",
                "user": "Joyce Weber",
                "text": "Non qui Lorem qui commodo sint in esse non aliqua pariatur mollit veniam. Elit labore ad nisi anim adipisicing tempor velit commodo adipisicing ipsum ut. Nostrud cillum aliquip adipisicing id do occaecat est eiusmod adipisicing duis. Magna dolore et non nisi in non cillum officia elit non esse proident irure aute. Proident mollit amet enim dolore eiusmod dolor qui. Eiusmod reprehenderit cillum sit deserunt nostrud enim duis excepteur. Excepteur pariatur sunt in ipsum id minim est mollit."
            }
        ]
    },
    {
        "id": "56c782f17b4e0ba78c7ad717",
        "date": "2016-04-09T18:03:23.000Z",
        "title": "Quis occaecat",
        "text": "Quis occaecat duis aliqua reprehenderit excepteur nisi deserunt excepteur elit magna. Magna cillum anim veniam deserunt voluptate occaecat irure fugiat laboris proident. Tempor do magna deserunt cillum laborum cillum ut.\n\nEst sunt cupidatat in deserunt sit aliqua duis. Mollit consequat duis aliquip occaecat pariatur non do eiusmod dolore amet deserunt ullamco. Ea minim tempor exercitation do tempor nostrud dolor minim veniam laboris commodo ex duis. Do nostrud voluptate ullamco consequat anim tempor voluptate incididunt aliqua tempor.\n\nIn irure quis nostrud do. Labore laboris irure culpa reprehenderit pariatur laboris in commodo culpa enim cillum magna. Magna ipsum pariatur sunt in reprehenderit ipsum duis officia voluptate adipisicing ad officia. Duis est sint mollit amet laborum magna non quis nulla ipsum in veniam sit. Amet velit consequat esse esse ea. Ipsum non do ut cillum in adipisicing labore non commodo do laborum sunt.",
        "comments": [
            {
                "id": "qwerqwertyy",
                "user": "Gilliam Underwood",
                "text": "Velit anim deserunt elit velit est fugiat duis eiusmod eu do incididunt ut tempor voluptate. Officia dolor aliqua id anim mollit pariatur id commodo. Laborum minim non ut aliquip commodo est consectetur. Mollit eu aliqua tempor est nulla ullamco irure. Sit non amet et eiusmod cillum ex cillum anim incididunt ad laboris mollit. Sunt quis incididunt elit ea qui non ullamco aliquip consequat voluptate eiusmod est. Irure laboris amet culpa sit aliquip."
            },
            {
                "id": "sdfgsdfghu7u7urtv",
                "user": "Jodi Humphrey",
                "text": "Non amet amet ut magna culpa dolore consequat occaecat. Commodo adipisicing laboris voluptate enim mollit mollit anim aliquip deserunt nostrud deserunt cillum est. Ad eu cupidatat dolor nostrud et minim id in dolor occaecat ad magna elit. Laboris elit laboris aliquip Lorem reprehenderit id amet reprehenderit laborum minim incididunt cupidatat eiusmod."
            }
        ]
    },
    {
        "id": "56c782f1978fdf9a0100df52",
        "date": "2016-06-02T11:03:23.000Z",
        "title": "Hello my new world",
        "text": "Culpa dolor deserunt veniam irure amet officia excepteur labore nisi labore ad labore laborum aute. Ea irure sit exercitation ex. Aliquip dolore duis ullamco labore qui. Et anim irure laborum quis ipsum. Adipisicing culpa est ea velit veniam dolor nisi. Sit cupidatat velit commodo eu.\n\nUt nulla ut irure cillum irure sint sunt cupidatat tempor laboris incididunt elit occaecat fugiat. Reprehenderit enim cupidatat consectetur pariatur ad pariatur consequat veniam do fugiat Lorem laborum do velit. Nulla aute magna magna nisi officia et. Aute adipisicing eu eiusmod tempor exercitation sint non enim laboris dolor adipisicing.\n\nEa do sint pariatur voluptate ad culpa irure. Cillum pariatur deserunt fugiat elit. Exercitation labore amet deserunt magna. Velit veniam aute officia aliqua ipsum veniam pariatur. Aliquip ullamco fugiat officia non sunt ad consequat ipsum est esse commodo reprehenderit. Ad quis consectetur est exercitation fugiat eiusmod. Laborum reprehenderit esse qui irure.",
        "comments": [
            {
                "id": "kjfviudfv089w74",
                "user": "Joyce Weber",
                "text": "Non qui Lorem qui commodo sint in esse non aliqua pariatur mollit veniam. Elit labore ad nisi anim adipisicing tempor velit commodo adipisicing ipsum ut. Nostrud cillum aliquip adipisicing id do occaecat est eiusmod adipisicing duis. Magna dolore et non nisi in non cillum officia elit non esse proident irure aute. Proident mollit amet enim dolore eiusmod dolor qui. Eiusmod reprehenderit cillum sit deserunt nostrud enim duis excepteur. Excepteur pariatur sunt in ipsum id minim est mollit."
            },
            {
                "id": "r23uyrghasdfb7",
                "user": "Joyce Weber",
                "text": "Non qui Lorem qui commodo sint in esse non aliqua pariatur mollit veniam. Elit labore ad nisi anim adipisicing tempor velit commodo adipisicing ipsum ut. Nostrud cillum aliquip adipisicing id do occaecat est eiusmod adipisicing duis. Magna dolore et non nisi in non cillum officia elit non esse proident irure aute. Proident mollit amet enim dolore eiusmod dolor qui. Eiusmod reprehenderit cillum sit deserunt nostrud enim duis excepteur. Excepteur pariatur sunt in ipsum id minim est mollit."
            }
        ]
    },
    {
        "id": "56c782f1e17f4f9311dfaa2c",
        "date": "2016-05-19T23:03:23.000Z",
        "title": "Voluptate est officia",
        "text": "Voluptate est officia pariatur tempor labore consequat consequat consectetur culpa enim. Amet laborum commodo in ullamco magna aliquip. Cupidatat veniam adipisicing labore irure nostrud sunt proident aute in. Sit Lorem consequat cillum enim id excepteur aliqua nostrud sint quis aute est est dolor. Sunt culpa est magna ad qui consequat exercitation. Enim sit ex do cupidatat laborum.\n\nOccaecat do tempor ex in dolor cupidatat do quis laboris anim. Et duis esse pariatur magna ex ipsum ut do ut id cillum. Nostrud fugiat sit minim ea. Nisi nulla sunt et et voluptate. Velit reprehenderit enim nulla mollit dolore excepteur Lorem do Lorem do cillum est qui. Ipsum mollit duis laboris incididunt non sit sunt proident. Aute voluptate id sunt aute proident officia.\n\nEnim ut nulla cillum officia cupidatat eiusmod amet laborum do labore id. Laborum in laboris aliquip anim consectetur magna reprehenderit consequat eiusmod esse Lorem consequat aliqua. Eiusmod voluptate mollit sint consectetur eu deserunt laboris ad et sunt nulla fugiat quis non. Dolor qui do cupidatat proident mollit amet sint pariatur non aliquip enim ex.",
        "comments": [
            {
                "id": "rflsbvyeuwr334rg5",
                "user": "Random Name",
                "text": "Non qui Lorem qui commodo sint in esse non aliqua pariatur mollit veniam. Elit labore ad nisi anim adipisicing tempor velit commodo adipisicing ipsum ut. Nostrud cillum aliquip adipisicing id do occaecat est eiusmod adipisicing duis. Magna dolore et non nisi in non cillum officia elit non esse proident irure aute. Proident mollit amet enim dolore eiusmod dolor qui. Eiusmod reprehenderit cillum sit deserunt nostrud enim duis excepteur. Excepteur pariatur sunt in ipsum id minim est mollit."
            },
            {
                "id": "234faasffasgfq3r3eda",
                "user": "Felix Soyferman",
                "text": "Non qui Lorem qui commodo sint in esse non aliqua pariatur mollit veniam. Elit labore ad nisi anim adipisicing tempor velit commodo adipisicing ipsum ut. Nostrud cillum aliquip adipisicing id do occaecat est eiusmod adipisicing duis. Magna dolore et non nisi in non cillum officia elit non esse proident irure aute. Proident mollit amet enim dolore eiusmod dolor qui. Eiusmod reprehenderit cillum sit deserunt nostrud enim duis excepteur. Excepteur pariatur sunt in ipsum id minim est mollit."
            },
        ]
    },
    {
        "id": "56c782f197fe2bad471b3740",
        "date": "2016-06-04T15:03:23.000Z",
        "title": "Ex sunt sunt aliqua",
        "text": "Ex sunt sunt aliqua reprehenderit aliqua occaecat. Minim anim commodo officia veniam proident aute cillum eu sunt aute nostrud. Laboris fugiat velit ut pariatur occaecat adipisicing pariatur occaecat. Duis sint enim et consectetur quis pariatur laborum excepteur. Ipsum aliquip qui laborum commodo consectetur do velit veniam occaecat. Ad nisi dolor cillum elit magna dolor voluptate ea. Enim in duis ea consequat sunt Lorem aute.\n\nEst elit sunt quis officia reprehenderit do elit commodo eiusmod esse voluptate. Sit ipsum commodo sint voluptate culpa labore elit magna ullamco nostrud. Laboris magna magna anim labore mollit irure voluptate. Aute non magna aliqua aliqua sunt. Velit mollit consectetur aliqua id tempor ut. Tempor cupidatat aliquip excepteur occaecat incididunt nulla Lorem sint.\n\nNon commodo anim deserunt in et aliquip incididunt ut consectetur sunt esse commodo deserunt et. Tempor fugiat laboris cillum laboris labore. Deserunt quis ad do labore amet culpa officia. Esse et officia nostrud tempor occaecat officia anim incididunt amet sunt excepteur Lorem. Aute occaecat magna velit nisi sit anim consequat velit qui pariatur. Esse incididunt id officia aliqua anim ut et.",
        "comments": [
            {
                "id": "23rfasdfasdvg",
                "user": "Hello World",
                "text": "Non qui Lorem qui commodo sint in esse non aliqua pariatur mollit veniam. Elit labore ad nisi anim adipisicing tempor velit commodo adipisicing ipsum ut. Nostrud cillum aliquip adipisicing id do occaecat est eiusmod adipisicing duis. Magna dolore et non nisi in non cillum officia elit non esse proident irure aute. Proident mollit amet enim dolore eiusmod dolor qui. Eiusmod reprehenderit cillum sit deserunt nostrud enim duis excepteur. Excepteur pariatur sunt in ipsum id minim est mollit."
            },
            {
                "id": "fqasfd4r35tga",
                "user": "Sofia Michailenko",
                "text": "Non qui Lorem qui commodo sint in esse non aliqua pariatur mollit veniam. Elit labore ad nisi anim adipisicing tempor velit commodo adipisicing ipsum ut. Nostrud cillum aliquip adipisicing id do occaecat est eiusmod adipisicing duis. Magna dolore et non nisi in non cillum officia elit non esse proident irure aute. Proident mollit amet enim dolore eiusmod dolor qui. Eiusmod reprehenderit cillum sit deserunt nostrud enim duis excepteur. Excepteur pariatur sunt in ipsum id minim est mollit."
            }
        ]
    },
    {
        "id": "56c782f1a2c2c3268ddb3206",
        "date": "2016-06-08T19:03:23.000Z",
        "title": "Commodo laborum sit nostru",
        "text": "Commodo laborum sit nostrud reprehenderit cupidatat officia laboris. Ipsum minim culpa in enim. Voluptate dolor ea irure nisi incididunt enim magna.\n\nCupidatat quis cillum velit culpa tempor esse irure nostrud ea consectetur officia fugiat irure qui. Enim quis officia do in. Velit veniam ipsum consequat aliqua duis voluptate. Minim nisi ex aute ad.\n\nNisi Lorem ex tempor adipisicing labore. Quis occaecat fugiat pariatur labore culpa cillum laboris. Labore occaecat ut laborum sit ex do sit. Deserunt consectetur elit aute laboris est deserunt officia ullamco sit laboris officia aliquip. Aliqua ut sunt nostrud voluptate excepteur quis incididunt Lorem ut.",
        "comments": [
            {
                "id": "23qwfasdf3",
                "user": "Brad McKeon",
                "text": "Non qui Lorem qui commodo sint in esse non aliqua pariatur mollit veniam. Elit labore ad nisi anim adipisicing tempor velit commodo adipisicing ipsum ut. Nostrud cillum aliquip adipisicing id do occaecat est eiusmod adipisicing duis. Magna dolore et non nisi in non cillum officia elit non esse proident irure aute. Proident mollit amet enim dolore eiusmod dolor qui. Eiusmod reprehenderit cillum sit deserunt nostrud enim duis excepteur. Excepteur pariatur sunt in ipsum id minim est mollit."
            },
            {
                "id": "dadsafw4f45w",
                "user": "Dolly Franklin",
                "text": "Aliquip id nostrud adipisicing irure. Labore reprehenderit ea ex officia ullamco incididunt consequat elit amet quis commodo. Fugiat amet veniam cillum ut aliquip velit est esse minim fugiat eiusmod sint. Commodo ea in culpa deserunt."
            },
            {
                "id": "234erasfdastw4a",
                "user": "Brennan Atkins",
                "text": "Nisi sit nisi cillum dolor fugiat sint do nostrud ex cillum cupidatat. Culpa do duis non et excepteur labore dolor culpa qui tempor veniam. Ex labore deserunt qui sit aute ad incididunt do cupidatat eiusmod reprehenderit ad. Qui laborum qui voluptate velit et consectetur ipsum enim dolore minim. Est sint velit tempor reprehenderit. Qui consectetur ad minim consequat."
            }
        ]
    },
    {
        "id": "56c782fghgfc2c3268ddb3206",
        "date": "2016-06-08T19:03:23.000Z",
        "title": "Lorem Ipsum dolor",
        "text": "Commodo laborum sit nostrud reprehenderit cupidatat officia laboris. Ipsum minim culpa in enim. Voluptate dolor ea irure nisi incididunt enim magna.\n\nCupidatat quis cillum velit culpa tempor esse irure nostrud ea consectetur officia fugiat irure qui. Enim quis officia do in. Velit veniam ipsum consequat aliqua duis voluptate. Minim nisi ex aute ad.\n\nNisi Lorem ex tempor adipisicing labore. Quis occaecat fugiat pariatur labore culpa cillum laboris. Labore occaecat ut laborum sit ex do sit. Deserunt consectetur elit aute laboris est deserunt officia ullamco sit laboris officia aliquip. Aliqua ut sunt nostrud voluptate excepteur quis incididunt Lorem ut."
    }

]


Теперь наш сайт будет выглядеть так.



В props мы можем передавать все что угодно. Это объект, который может передавать в компонент данные. Например

<Article article={articles[0] foo="bar"}/> - передаем строку и нам не нужно заворачивать ее в фигурные скобки.

<Article article={articles[0] flag={ true }}/> передали флажок. Можно передать просто flag без значений и он передастся как true Таким образом мы разбили наше приложение на компоненты и связали их между собой. Подключили вывод текста одной статьи. Продолжение знакомства с React.js смотрите в следующей части - React.js (3) Там мы будем добавлять интерактивность нашим компонентам. Поставим кнопку с изменяющимся текстом для открытия\скрытия статьи.
Все статьи по React.js

                                                                                                                                                             

понедельник, 7 мая 2018 г.

React.js Настройка окружения.

Самый простой способ настроить среду для запуска приложения на react.js это установить готовый пакет Create React App от разработчиков Facebook



Почему приложение Create React App?


Просто потому. что вместе с ним мы получим готовый, настроенный сервер, Babel интерпретатор, Webpack для сборки и другие плюшки, в виде свободы в написании кода без префиксов для кросбраузерности и настроенную среду для тестирования и сборки приложения. В вашей среде будет все, что вам нужно для создания современного приложения React:
  • React, JSX и ES6.
  • Языковые дополнительные функции за пределами ES6, такие как spread operator объектов.
  • Dev-сервер, который накладывает на обычные ошибки.
  • Импортируйте файлы CSS и изображений непосредственно из JavaScript.
  • Autoprefixed CSS, поэтому вам не нужны -webkit или другие префиксы.
  • Сценарий сборки для объединения JS, CSS и изображений для производства с sourcemaps.


Для начала нам потребуется установленный Node.js с менеджером пакетов npm или yarn.

Чтобы проверить, установлен ли на ваш компьютер Node.js, а npm - пакеты к нему устанавливаются по умолчанию, то введите в КС - командной строке, или bash - node -v.Должны получит версию ноды. Например: v8.5.0




  1. Идем на сайт gitHub - create-react-app
    или его русскоязычный аналог - create-react-app-rus

  2. Устанавливаем приложение глобально. В КС - командной строке (или Bash) вводим:

    npm install -g create-react-app

  3. Ждем окончания установки и переходим в директорию (команда cd), где будет создаваться папка нашего приложения. В КС набираем:

    create-react-app my-app

    В данном случае - my-app - название папки вашего приложения.

  4. Открываем папку нашего проекта my-app в редакторе и удаляем из папки public все файлы кроме index.html




  5. В файле index.html удаляем все и добавляем самый простой код страницы:

  6. 
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <title>React App</title>
      </head>
      <body>
        
        <div id="root"></div>
    
      </body>
    </html>
    
    


  7. В папке src оставляем только файл index.js с кодом, где будет например такой код (файл полностью):

  8. 
    import React from 'react'
    import {render} from 'react-dom'
    
    function Article() {
      const body = <section>Footer</section> 
     return(
          <div className="hello" style={{color:"red"}}>
            <h2>title</h2>
            <section>body</section> 
            { body }
            <h3 style={{color:"red"}}>
             "creation date : "{ (new Date()).toDateString()}
            </h3>
          </div>
        );
    }
    
    function App() {
     return (
        <div>
            <h1>App Name</h1>
            <Article/>
        </div>
      );
    }
    
    render(<App/> ,document.getElementById('root'))
    
    
    


  9. Сохраняем и переходим непосредственно в наше приложение - >
    cd my-app

    A для запуска сервера на локальном хосте 3000 в КС набираем:
    npm start

    Появится сообщение, что сайт запущен на локальном хосте по адресу -http://localhost:3000




  10. Перейдите по этому адресу и вы должны увидеть вот такую страницу




  11. Остановить сервер - Ctrl + C


Создание нового и открытие старого приложения.


Теперь, когда у вас на машине установлен пакет create-react-app глобально, вы можете с легкостью его развернуть в любой папке для создания нового react-приложения. Это очень удобно. Я делаю так:

  1. выбираю директорию в проводнике и нажимаю правую кнопку мыши.




  2. В выпадающем меню выбираю - Git Bush Here

  3. Далее все, как в примере выше, с пункта 3, или просто делаю
    npm start
    для запуска уже созданного приложения на локальном хосте.


Надеясь, что вам было понятно и я не слишком утомил вас подробными объяснениями. Дело в том, что информации по React.js действительно много, но порой она больше касается теории, или опускает какие-то моменты, которые авторам кажутся очень простыми и само-собой разумеющиеся, но это осложняет жизнь начинающим пользователям. Да, и приятно, когда нужные, простые заметки всегда под рукой.

Подписывайтесь на мой блог и не забывайте поделиться, чтобы не потерять, если вам понравилось.

Следующая часть - React (2) - разбить на компоненты                                                                                                                                                              

четверг, 3 мая 2018 г.

ES6 для начинающих (3).


Часть 1 статьи можно прочитать здесь.

Часть 2 статьи.



Темы, которые я расскажу в этой статье:
  1. Array map
  2. Array filter
  3. Array reduce
  4. Template literals
  5. Imports and exports
  6. Destructuring objects and arrays
  7. Extend and super


Array Map

Оператор Map используется для выполнения конкретной операции над всеми элементами массива и возвращает массив с модифицированными элементами.

Это очень легко реализовать. Давайте посмотрим пример.

let arr = [1,2,3,4,5];
let modifiedArr = arr.map(function(element, index, arr) {
  return element * 10;
});
console.log(modifiedArr);
Output:
[10, 20, 30, 40, 50]



Как видите, map принимает функцию с тремя параметрами.
  1. Первый параметр - это сам элемент.
  2. Второй параметр - это индекс элемента.
  3. Третий параметр - это весь массив.


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

Еще одна вещь, которую я хотел бы добавить, - второй и третий параметр, является необязательным. Обязателен только первый параметр.

let modifiedArr = arr.map(function(element) {
  return element * 10;
});



Как вы видите, map принимает функцию с одним параметром.

Хорошо. Давайте попробуем написать map со стрелочными функциями.

let modifiedArr = arr.map((element, index) => {
  console.log("index "+index);
  return element * 10;
});
console.log(modifiedArr);
Output:
index 0
index 1
index 2
index 3
index 4
[10, 20, 30, 40, 50]



Думаю, мне не нужно много объяснять. Это просто.

Последний пример.

let modifiedArr = arr.map(element => element * 10);
console.log(modifiedArr);



Если вы знаете, стрелочные функции хорошо, это легко понять. Но если нет, то я попытаюсь объяснить.

Здесь есть две вещи.
  1. Если у вас есть функция с единственным параметром, вам не нужны круглые скобки - (). В нашем случае элементом является параметром.
  2. И если у вас есть единственная строка как тело функции, вам не нужны фигурные скобки - {}, а также JS будет неявно возвращать значение после выполнения функции. Вам не нужно использовать ключевое слово return.


Array Filter

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

Давайте посмотрим пример.

let arr = [1, 2, 3, 4, 5, 6]
let modifiedArr = arr.filter(function(element, index, array) {
  return element % 2 == 0
});
console.log(modifiedArr);
Output:
[2, 4, 6]



Как видно из приведенного выше примера, filter, подобно map, принимает три параметра.

И мы должны вернуть логическое значение для каждого элемента массива. Если вы не вернете какое-либо логическое значение в конце, тогда фильтр примет его как false и удалит элемент.

Хорошо .. Давайте попробуем это в стрелочной функции.

let modifiedAarr = arr.filter((element, index) => element%2 == 0)



Надеюсь, вы поняли. И не забывайте об этом, только первый параметр является обязательным. Другие два параметра являются необязательными.

Array Reduce

Array Reduce используется для агрегирования всех элементов массива и возврата одного значения. Давайте посмотрим пример

let arr = [1,2,3,4,5,6]
let total= arr.reduce(function(sum, element, index, array) {
  return sum + element;
},0);
console.log("total is "+total);
Output:
total is 21



В отличие от filter и map, сокращение принимает функцию с четырьмя параметрами, а также дополнительный элемент. В нашем случае это 0.

Давайте посмотрим, как это работает.

Первый параметр - это элемент агрегатора. Он имеет сумму элементов в любой заданной точке. И это начальное значение определяется как дополнительный элемент. В нашем случае это 0.

Затем второй, третий и четвертый параметры такие же, как у filter и map.

Как и в функциях filter и map, вы должны вернуть конечный результат.

Давайте посмотрим другой пример.

let arr = [1,2,3,4,5,6];
let totalSum = arr.reduce(function(sum, element, index, array) {
  console.log(sum+"+"+element+"="+sum+element);
  return sum + element;
}, 10);
console.log("Total sum is "+ totalSum);
Output:
10 + 1 = 11
11 + 2 = 13
13 + 3 = 16
16 + 4 = 20
20 + 5 = 25
25 + 6 = 31
Total sum is 31



Надеюсь, это понятный пример. Обратите внимание, что я сначала установил начальное значение суммы sum, элемента агрегатора на 10.

Давайте напишем тот же код со стрелочными функциями.

let totalSum = arr.reduce((sum, element) => element+sum, 0)



Надеюсь, вы поняли. Это легко.

В отличие от filter и map, первые два параметра являются обязательными. Другие два являются необязательными.

Template Literals

Если вы знаете другие языки программирования, такие как ruby, python, то Template Literals для вас не новы.

Это новый синтаксис, который упрощает добавление выражений.

Template Literals используются для выполнения любых выражений JS.

Давайте посмотрим пример

let name = "Jon Snow";
let msg = `My name is ${name}`;
console.log(msg);
Output:
My name is Jon Snow



всё очень просто.

Вы также можете использовать многострочные строки- multi-line strings.

let msg = `My name
is ${name}`;
console.log(msg);
Output:
My name
is Jon Snow



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

let name = "Srebalaji";
let languages = () => {return "Ruby, Js, Java, Python"}
let msg = `My name is ${name}
My age is ${20+3}
And I code in ${languages()}`
Output:
My name is Srebalaji
My age is 23
And I code in Ruby, Js, Java, Python



Надеюсь, вы поняли. Идем дальше. Вы можете добавить любое выражение легко, а также многострочные строки (multi-line strings).

Imports and Exports

Импорт и экспорт модулей в ES6 - одна из полезных функций, которые вы увидите в современных библиотеках интерфейсов.

Я очень рекомендую поиграть с этой функцией в этом Plunk. Окружающая среда уже настроена в этом Plunk.

Хорошо .. Так импорт и экспорт работают в ES6.

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

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

Если вы не устали. то давайте посмотрим пример.

app.js
export let name = "Jon"
export let age = 23
index.js
import {name, age} from './app'
console.log(name);
console.log(age);
index.html

Output:
Jon
23



В приведенном выше примере мы определили две переменные name и age переменных и экспортировали их.

В другом файле мы импортировали переменные и получили доступ к их значениям.

Это очень просто.

Пойдем глубже.

app.js
export default const name = "Jon"
index.js
import name from './app.js'
console.log(name);
Output:
Jon



В приведенном выше коде вы видите, что мы использовали новое ключевое слово default - по умолчанию. Значения по умолчанию в основном используются, если вам нужно экспортировать одно значение, функцию или объект из модуля. И в модуле может быть только одно значение по умолчанию - default value.

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

Пример:

import n from './app.js'
console.log(n);
Output:
Jon



Как вы можете видеть, мы указали значение по умолчанию - n здесь.

Пойдем глубже.

app.js
let a = 10;
let b = 2;
let sum = () => a+b;
export {a,b}
export default sum
index.js
import * as variables from './app'
import addition from './app' // default value
console.log(variables.a);
console.log(variables.b);
console.log(addition());
Output:
10
2
12



В приведенном выше примере вы можете видеть, что мы экспортировали две переменные и функцию. И мы импортировали все переменные, используя *.

При импорте есть две вещи.
  1. Если вы используете * для импорта значений, вы должны использовать псевдонимы - alias, которые будут ссылаться на импортированные значения. В нашем примере мы использовали переменные - variables как псевдоним.
  2. Использование * для импорта значений не импортирует значение по умолчанию. Вы должны импортировать их отдельно.


import addition, * as variables from './app'



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

Надеюсь, вы поняли. :)

Destructuring objects and arrays

Деструктуризация является одной из полезных функций в ES6. И это очень просто использовать.

Приведем пример.

let person = {firstName: "Jon", lastName: "Snow", age: 23}
const {firstName, lastName, age} = person
console.log(firstName);
console.log(lastName);
console.log(age);
Output:
Jon
Snow
23



В приведенном выше коде вы можете видеть, что у нас есть объект person с несколькими ключами.

И мы создали три переменные firstName, lastName, age (то же самое, что и ключи объектов.) из самого объекта.

Чтобы выразить это простыми словами, мы создали три переменные извлечением ключей из объекта.

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

let person = {firstName: "Jon", lastName: "Snow", age: 23}
const {firstName} = person
console.log(firstName);
Output:
Jon



В приведенном выше примере вы можете видеть, что мы извлекли из объекта только требуемые значения.

let person = {firstName: "Jon", lastName: "Snow", age: 23}
const {firstName: name, age} = person
console.log(name);
console.log(age);
Output:
Jon
23



В приведенном выше примере вы можете видеть, что мы определили новое имя переменной и присвоили значение firstName.

Надеюсь, вы поняли. Это просто.

Давайте посмотрим, как деструктурировать массив - destructure array.

let arr [1, 2, 3, 4]
const [a, b, c, d] = arr;
console.log(a);
console.log(b);
console.log(c);
console.log(d);
Output:
1
2
3
4



Надеюсь, вы уловили это из кода выше. Это просто.

Мы присваиваем каждому элементу массива переменную.

Давайте посмотрим другой пример.

let arr = [1,2,3,4,5,6]
let [a,b,,d,e] = arr
console.log(a);
console.log(b);
console.log(d);
console.log(e);
Output:
1
2
4
5



В приведенном выше коде вы можете видеть, что мы пропустили третий элемент массива. Помимо этого все так же, как в предыдущем примере.

Давайте посмотрим другой пример.

let person = {firstName: "Jon", lastName: "Snow", age: 23}
let displayName = ({firstName, lastName:last}) => {
  console.log(`${firstName} - ${last}`);
}
displayName(person);
Output:
Jon - Snow



Надеюсь, вы поняли. идем дальше.

Extend and Super

Если у вас есть опыт кодирования в OОП (объектно-ориентированном программировании), то >Extend - расширение и Super - супер не новы для вас.

Extend используется для создания подкласса из основного класса. Подкласс наследует все свойства основного класса и также может изменять свойства основного класса.

class Person{
 constructor(firstName, lastName, age) {
   this.firstName = firstName;
   this.lastName = lastName;
   this.age = age;
 }
 displayName() {
  return `${this.firstName} - ${this.lastName}`;
 }
}
class Employee extends Person {
 constructor(firstName, lastName, age, salary) {
  super(firstName, lastName, age);
  this.salary = salary;
 }
 displaySalary() {
  return `${this.salary}`;
 }
 displayName() {
  return super.displayName();
 }
 displayAge() {
  return this.age;
 }
}
let manager = new Employee("Jon", "Snow", 23, 100);
console.log(manager.displaySalary());
console.log(manager.displayName());
console.log(manager.displayAge());
Output:
100
Jon Snow
23



В приведенном выше коде вы можете видеть, что мы определили класс Person с конструктором и простой метод.

И тогда мы определили еще один класс Employee, который является подклассом, унаследованным от Person. Для этого мы использовали расширения - Extend. Надеюсь, что это ясно.

И затем мы использовали ключевое слово super, чтобы вызвать конструктор родительского класса. И мы также вызвали метод, объявленный в родительском классе, используя super.
Примечание: вы можете использовать this в подклассе только после вызова super. Если вы используете this перед вызовом super в подклассе, вы получите RefrenceError.

Итак, мы достигли трех вещей в приведенном выше коде
  1. Мы использовали расширения Extend для создания подкласса из родительского класса.
  2. Мы использовали super для вызова конструктора родительского класса.
  3. Мы использовали super для вызова метода, определенного в родительском классе.
Надеюсь, у вас это получилось :)

Здесь можно немного поиграть и потренировать свои знания


Часть 1 статьи здесь.

Часть 2 статьи здесь.






Автор: Srebalaji Thirumalai.
Перевод: Kolesnikov Yaroslav



                                                                                                                                                             

среда, 2 мая 2018 г.

ES6 для начинающих (2)


Первую часть этой статьи вы можете найти здесь.Там есть некоторые интересные функции. :)



Темы, которые я расскажу в этом посте
  1. Promises - Промисы (обещания)
  2. Async / Await


Promises

Promises - Обещания являются одной из полезных функций в ES6. Они используются для выполнения асинхронных операций, таких как запрос API, обработка файлов, загрузка изображений и т. д.

Итак, что такое Async? (держитесь, если вы уже знаете)

Асинхронные операции - это операции, требующие некоторого времени для завершения.

Например, скажем, вы определяете функцию, которая делает запрос API на сервер. Эта функция не возвращает результат немедленно. Для получения ответа от сервера требуется несколько секунд.

Поэтому, если вы вызываете эту функцию и присваиваете ее значение для некоторой переменной, она будет undefined не определено. Поскольку Javascript не знает, что функция обрабатывает некоторые операции async.

Итак, как мы справляемся с этим?

До этого поговорим немного о истории.

Перед обещаниями - promise программисты использовали обратные вызовы - callbacks. Обратные вызовы являются нормальными функциями в Javascript, который выполняется, когда операция async завершена.

Например, вы определяете функцию, которая делает запрос API на сервер. Затем вы указываете функцию обратного вызова, которая будет выполняться, когда мы получим ответ от сервера.

Таким образом, в приведенном выше случае Javascript не останавливает выполнение, пока мы не получим ответ от API. И мы определили функцию callback, которая будет выполнена после получения ответа. Думаю, это понятно.

Итак, что такое обещания - promises





Обещания promises- это объекты, которые помогают выполнять асинхронные операции.

Технически это объекты, которые представляют собой завершение операции async. (Если вы что-то не получите, то остаетесь на некоторое время.)

Прежде чем объяснять, как определить обещание promises, я объясню жизненный цикл обещания.

У нас есть три состояния в promises.
  1. Pending Ожидание: в этом состоянии обещание (promises) просто выполняет операцию async. Например, он делает некоторый запрос API на сервер или загружает некоторые изображения из cdn. Из этого состояния (promises) обещания можно перейти либо к Fulfilled - исполнению, либо к Rejected - отказу.
  2. Fulfilled : Если (promises) обещание достигло этого состояния, значит, операция async завершена, и у нас есть выходные данные - output. Например, у нас есть ответ от API.
  3. Rejected : Если (promises) обещание достигло этого состояния, это означает, что асинхронная операция не увенчалась успехом, и у нас есть ошибка, из-за которой операция завершилась неудачей.


Хорошо ... Давайте посмотрим на некий код.

const apiCall = new Promise(function(resolve, reject) {
 // async operation is defined here...
});



Promise определяется созданием конструктора с использованием ключевого слова - new. Тогда конструктор будет иметь функцию (мы называем ее executor function - функцией-исполнителем).

Асинхронная операция определяется внутри функции-исполнителя.

Обратите внимание, что функция-исполнитель имеет два параметра, которые resolve - разрешают или reject - отклоняют.

Первое решение параметра - фактически функция. Он вызывается внутри функции-исполнителя и представляет, что операция async успешна, и мы получаем результат. Функция Resolve помогает обещать перейти от pending -ожидаемого к fulfilled - исполненному состоянию. Надеюсь, вы поняли. :)

Подобно решению, reject также является функцией. Он также вызывается внутри функции-исполнителя, и он показывает, что операция async не выполняется, и мы получили ошибку. Отклонение помогает обещанию перейти от ожидания - pending к отклонению - reject. :)

const apiCall = new Promise(function(resolve, reject) {
 if ( API request to get some data ) {
  resolve("The request is successful and the response is "+ response);
 }
 else {
  reject("The request is not successful. The error is "+error);
 }
});



В приведенном выше коде вы можете видеть, что мы выполнили некоторую асинхронную операцию внутри функции-исполнителя. Затем вызывается функция resolve разрешения, если мы получаем ответ от сервера. И если есть некоторая ошибка, то функция reject error вызывается с сообщением об ошибке.

Мы сделали определение promises - обещания. Давайте посмотрим, как выполнить promises - обещание и обработать результат.

// calling the promise.
apiCall



Это оно. мы сделали. :) :)

Просто шучу. Это еще не конец.

В приведенном выше коде функция вызывается и выполняется обещание (т. Е. Выполняется executor function исполнительская функция). Затем вызывается функция resolve - разрешения или reject -отклонения на основе вывода - output.

Но вы можете видеть, что мы не обрабатывали результат, полученный из promise- обещания.

Например, если мы получим ответ от API, мы должны обработать ответ. Или, если мы получим ошибку, нам нужно правильно ее обработать.

Итак, как мы справляемся с этим?

Мы используем обработчики - handlers для получения результата от обещания.

Обработчики (handlers)- это просто функции, которые выполняются, когда происходит какое-то событие, например, нажатие кнопки, перемещение курсора и т. д.

Таким образом, мы можем использовать обработчики для обработки при вызове функции resolve - разрешения или reject - отклонения функции.

Просто. :)

Давайте посмотрим, такой код:

// calling the promise with some handlers.
apiCall.then(function(x) {console.log(x); })



В приведенном выше коде мы приложили обработчик (handler) к (then) обещанию (promise). Затем - then обработчик получает параметр функции. Тогда сам параметр функции имеет параметр x.

Так что происходит.

Обработчик then выполняет function parameter, когда функция resolve вызывается внутри обещания (promise).

Я попытаюсь объяснить это снова.

Обработчик then ищет случай, когда вызывается функция разрешения. Поэтому, когда функция разрешенияresolve вызывается, then обработчик выполняет свой параметр функции.

apiCall.then(function(x) {console.log(x); })
// Output
The request is successful and the response is {name: "Jon Snow"}



Аналогично, есть еще один catch захват обработчика.

Обработчик catch ищет функцию отклонения - reject .

Функция catch выполняет свой функциональный параметр при вызове функции reject.

apiCall.then(function(x) {console.log(x); }).catch(function(x) {console.log(x); })
// Assuming the request is not successful ( reject function is called in the promise. )
Output:
The request is not successful



Думаю, вы поняли.

Вышеприведенный код недостаточно читабельен. Так давайте попробуем:

apiCall
.then(function(x) {
 console.log(x); 
})
.catch(function(x) {
 console.log(x);
}) 



Теперь это можно прочитать. Большинство программистов пишут это так.

Хорошо. Поэтому я думаю, что вы прошли долгий путь.

Давайте резюмировать..
  1. Promise определяется с помощью нового ключевого слова с параметром функции. Тогда сама функция имеет два параметра функции, которые разрешают - resolve и отклоняют - reject.
  2. Функция resolve будет вызвана, когда операция выполнена успешно.
  3. Функция reject - когда операция даст сбой.
  4. Обработчик then ищет функцию resolve разрешения.
  5. Обработчик catch ищет функцию reject отклонения.
  6. Удостоверьтесь в удобочитаемости кода :) :)
Вот рабочий пример - jsfiddle.net. Пожалуйста, попрактикуйтесь, если вы новичок в этом.


Надеюсь,что вы поймете пример. Тогда вперед.

Async / Await

Если вы понимаете Promise, то Async / Await довольно легко. И если вы не поняли Promise, Async / Await может помочь вам понять это. Может быть, вы также сможете получить ясный выход из Promise - обещаний. :)

Async

Ключевое слово Async позволяет любой функции возвращать только обещания.

Например, рассмотрите приведенный ниже код

async function hello() {
 return "Hello Promise..!"
}



Function hello вернет Promise - обещание.

Вышеприведенный код эквивалентен приведенному ниже коду.

function hello() {
 return new Promise(function(resolve, reject) {
 // executor function body.
 });
}



Так проще?

Другой пример:

async function hello(a, b) {
 if (a < b) {
  return "Greater";
 }
 else {
  return new Error("Not Greater");
 }
}
hello(14, 10)
.then(function(x) {
 console.log("Good..! " + x); 
})
.catch(function(x) {
 console.log("Oops..! " + x); 
})
Output:
Oops..! Not Greater. 
// if you call hello(4, 10) you get "Good..! Greater"



В приведенном выше коде мы определили функцию async и вернули некоторое значение или вернули некоторую ошибку.

Если вы возвращаете некоторое значение в async-функции, это эквивалентно вызову функции resolve разрешения.

Если вы возвращаете некоторую ошибку, вызывая error constructor using ‘new’ (конструктор ошибок с помощью «new»), то это эквивалентно функции reject - отклонения.

Не забывайте, что функция async вернет обещание. Поэтому, конечно, вы можете вызвать функцию resolve - разрешения и отклонения - reject внутри функции async.

Посмотрим, как это работает.

async function Max(a, b) {
 if (a > b) {
  return Promise.resolve("Success");
 }
 else {
  return Promise.reject("Error");
 }
}
Max(4, 10)
.then(function(x) {
 console.log("Good " + x); 
})
.catch(function(x) {
 console.log("Oops " + x); 
});
Output:
Oops Error
// If we pass Max(14, 10) then we should get "Good Success" :)



Await

Как следует из названия, это заставляет Javascript ждать завершения операции. Предположим, вы делаете запрос API с ключевым словом await. Это заставляет Javascript ждать, пока вы не получите ответ от конечной точки. И затем он возобновляет выполнение.

Хорошо .. Пойдем глубже

Ожидание await может использоваться только внутри асинхронной функции. Он не работает вне асинхронной функции
Давайте посмотрим пример:

async function hello() {
 let response = await fetch('https://api.github.com/');
 // above line fetches the response from the given API endpoint.
 return response;
}
hello()
.then(function(x) {
 console.log(x); 
});
...
...
Output:
Response from the API.



В приведенном выше коде вы можете видеть, что мы использовали await ожидание при получении ответа от API.

Операция выборки (fetch) может занять несколько секунд, чтобы получить ответ так, что выполнение будет остановлено и возобновлено позже.

Обратите внимание, что ожидание операции останавливает выполнение внутри функции hello. Остающийся код вне функции hello не будет затронут. Выполнение продолжается вне функции. И когда мы получаем ответ, выполняется параметр функции .then внутри обработчика .

Надеюсь, вы поняли.

Давайте посмотрим пример

jsfiddle.net



В приведенном выше примере вы можете видеть, что мы использовали await функцию для getResponse. И getResponse вернет результат или ошибку через 5 секунд. Таким образом, до этого времени выполнение приостанавливается, а затем возвращается ответ.

Давайте посмотрим пример в реальном времени.

jsfiddle.net



В приведенном выше примере вы можете видеть, что мы использовали несколько ожиданий - awaits. Поэтому для каждого ожидания выполнение останавливается до получения ответа, а затем возобновляется.

Попробуйте использовать тот же пример с некорректным URL-адресом. Вы можете видеть, что ошибка поднята.

Обработка ошибок очень проста в асинхронной async функции. Если ошибка возникает внутри функции async или когда ошибка возникает из других функций, которые вызываются внутри async, используя await, вызывается функция reject - отклонения. Просто.

Надеюсь тебе понравилось. Я рассмотрю гораздо более интересные темы, такие как карта массива, фильтр массивов, сокращение и т. д. В следующей части.




Автор: Srebalaji Thirumalai.
Перевод: Kolesnikov Yaroslav




                                                                                                                                                             


Хотите освоить самые современные методы написания React приложений? Надоели простые проекты? Нужны курсы, книги, руководства, индивидуальные занятия по React и не только? Хотите стать разработчиком полного цикла, освоить стек MERN, или вы только начинаете свой путь в программировании, и не знаете с чего начать, то пишите через форму связи, подписывайтесь на мой канал в Телеге, вступайте в группу на Facebook.Пишите мне - kolesnikovy70 почта gmail.com