Koa.js — это выразительная веб-инфраструктура следующего поколения, написанная для Node.js людьми, работающими над платформами Express и Connect. Koa.js использует генераторы, которые являются передовой особенностью JavaScript и еще не были превращены в стабильные версии Node.js. Koa стремится использовать генераторы, чтобы избавить разработчиков от спагетти обратных вызовов, делая его менее подверженным ошибкам и, следовательно, более управляемым.
Koa — всего 550 строк кода — чрезвычайно легкая структура. Даже после этого Koa упаковывает в элегантный набор методов, таких как согласование содержимого, перенаправления, поддержка прокси и т. Д., Обеспечивая простоту и скорость разработки, а также детальный контроль над приложением вашего узла.
Установка узла
Теперь, прежде чем мы начнем, вам понадобится как минимум Node версии 0.11.x
или выше.
Вы можете установить последнюю версию Node, используя модуль N:
1
2
|
sudo npm install -gn
sudo n stable
|
Вы также можете использовать другие модули сообщества, такие как nvm или создать его из исходного кода. Обратите внимание, что N также является модулем сообщества.
Чтобы запустить файл JS, в котором используются генераторы, вам необходимо --harmony
флаг --harmony
при его запуске.
Например, чтобы запустить app.js
, введите следующую команду:
1
|
node —harmony app.js
|
Или чтобы не вводить этот флаг каждый раз, вы можете создать псевдоним с помощью следующей команды:
1
|
alias node=»node —harmony»
|
Теперь, чтобы запустить ваше приложение с помощью генераторов, просто введите:
1
|
node app.js
|
Очень хорошо! Также имейте в виду, что весь код этой статьи доступен на GitHub . Не стесняйтесь раскошелиться и поиграть с ним.
Теперь, чтобы понять Коа, вы должны сначала понять генераторы, которые формируют позвоночник каркаса.
Что такое генераторы?
С ES-6 генераторы наконец-то приземлились в волшебной стране JavaScript. Если у вас есть опыт работы с генераторами в Lua, Python, Scheme, Smalltalk и т. Д., То вам будет приятно узнать, что в JavaScript реализована очень похожая вещь.
Генераторы — это первоклассные сопрограммы в JavaScript, которые, проще говоря, вводят интерфейс паузы и воспроизведения в языке. До генераторов весь скрипт обычно выполнялся в порядке сверху вниз, без простого способа остановить выполнение кода и возобновить работу с тем же стеком позже. Теперь давайте запачкаем руки примерами.
В соответствии с текущим проектом спецификации ES-6 нам нужно использовать другую версию определения функции для создания функции генератора. Это выглядит так:
1
|
var generator_func = function* () { };
|
Здесь generator_func
— это просто пустая функция генератора.
Поэтому мы можем использовать ключевое слово yield
в функции, чтобы остановить выполнение и сохранить текущий стек.
Вот простой пример, демонстрирующий сумму бесконечного AP:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
var r = 3;
function* infinite_ap(a) {
for( ; ; ) {
a = a + r;
yield a;
}
}
var sum = infinite_ap(5);
console.log(sum.next());
console.log(sum.next());
|
В приведенном выше коде мы изначально создаем экземпляр итератора с именем infinite_ap
который включает в себя бесконечный цикл и, если он выполняется в нормальных условиях, может заморозить выполнение.
Далее мы сохраняем экземпляр итератора в переменной sum
.
Теперь, когда мы вызываем sum.next()
, он возвращает { value: 8, done: false }
что означает, что он остановил свое выполнение в операторе yield
возвращающем value
как «a» и done
как «false».
Здесь done
возвращает false, пока выполнение не будет завершено. Когда выполнение завершено (в вышеупомянутом случае это никогда не происходит), функция возвращает {value: undefined, done: true}
.
Вот небольшая модификация предыдущего кода, чтобы продемонстрировать конец выполнения:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
var r = 3;
function* infinite_ap(a) {
for( var i = 0; i < 3 ; i++) {
a = a + r ;
yield a;
}
}
var sum = infinite_ap(5);
console.log(sum.next());
console.log(sum.next());
console.log(sum.next());
console.log(sum.next());
|
В более сложных программах вы должны проверять и использовать возвращаемые значения и состояние « done
.
Примечание : использование yield
без function*
приведет к ранней ошибке.
Доступные методы генераторов
Вот несколько распространенных методов, которые пригодятся вам при работе с ванильными генераторами.
Каждый из методов ниже доступен только в функции генератора и в противном случае выдает ошибку.
next()
Это используется для возобновления выполнения вместе с передачей аргумента. Если ничего не передано, то undefined передается в качестве первого аргумента.
Пример: sum.next(5);
throw()
Это используется, чтобы вызвать ошибку или исключение на любом этапе. Это делает обработку ошибок намного проще. Выдача ошибки может привести к остановке выполнения файла, если он где-то не обрабатывается. Самый простой способ обработки ошибки — использовать оператор try и catch. Этот метод принимает один аргумент, который может быть чем угодно.
Пример: sum.throw(new Error("this is an error"));
Делегирование yield
Делегирование генератора используется для получения генератора из существующего генератора и может использоваться для создания генераторов или даже итерации по генератору.
При делегировании другому генератору генератор тока прекращает производить само значение и начинает давать значения делегированного генератора, пока он не будет исчерпан. После исчерпания делегированного генератора генератор возобновляет возврат своего собственного значения.
Это очень похоже на использование цикла for-in
над генератором, но исключения делегированного генератора распространяются и генерируются с помощью метода throw
внешнего генератора и должны обрабатываться аналогичным образом. Вот пример:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
var consoleLogThunk = function(msg) {
return function() {
console.log(msg);
}
}
var generator = function*() {
yield consoleLogThunk(«Yo»);
yield consoleLogThunk(«Dawg»);
yield consoleLogThunk(«!!!»);
}
var delegator_function = function* () {
yield consoleLogThunk(«I yielded before delegated yield»);
yield* generator();
yield consoleLogThunk(«I yielded after delegated yield»);
}
var k = delegator_function();
k.next().value();
k.next().value();
k.next().value();
console.log(k.next());
|
Теперь, когда у вас есть краткое представление о генераторах в Javascript, вы можете использовать их для написания гораздо более понятных и менее подверженных ошибкам приложений, в которых вы можете блокировать ввод-вывод, фактически не блокируя процесс.
Давайте теперь перейдем к установке Koa и очень простого приложения на основе Koa.js.
Koa.js:
Koa — это объект, который содержит массив функций генератора промежуточного программного обеспечения, все из которых составляются и выполняются стековым способом при каждом запросе.
Установка коа
В каталоге вашего проекта выполните следующую команду.
1
|
npm install koa —save
|
Koa будет автоматически загружен и сохранен в файле package.json
, если он существует.
Несмотря на то, что Koa занимает очень мало места, он включает методы для таких задач, как обновление кэша, согласование контента, перенаправления, поддержка прокси и т. Д., Без промежуточного программного обеспечения.
Вот пример приложения hello-world:
1
2
3
4
5
6
7
8
|
var koa = require(‘koa’);
var app = koa();
app.use(function *(){
this.body = «Hello World !!!»;
});
app.listen(3000);
|
Поток управления Коа
Теперь Коа также осуществляет нисходящий поток с последующим восходящим потоком управления. Сначала это может быть трудно задыхаться, но как только вы пройдете через пример ниже, все станет яснее.
Вот пример потока управления в Коа:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
var koa = require(‘koa’)();
koa.use(function* (next) {
//do something before yielding/passing to next generator function in line which will be 1st event in downstream
console.log(«A»);
yield next;
// do something when the execution returns upstream, this will be last event in upstream
console.log(«B»);
});
koa.use(function* (next) {
// do something before yielding/passing to the next generator function in line, this shall be 2nd event downstream
console.log(«C»);
yield next;
// do something when the execution returns upstream and this would be 2nd event upstream
console.log(«D»);
});
koa.use(function* () { // do something before yielding/passing to next generator function in line. Here it would be last function downstream
console.log(«E»);
this.body = «hey guys»;
console.log(«F»);
});
koa.listen(3000);
|
Код выше довольно прост. Обратите внимание, что не все операторы console.log
являются обязательными, но они помогут вам четко понять нисходящий и восходящий поток выполнения Koa.js.
Понимание последовательности выполнения примеров
Когда мы запускаем это приложение и открываем localhost:3000
в браузере, мы видим, что console.logs
в терминале не в порядке ABCDEF . И при этом они не в порядке ACEBDF .
Порядок на самом деле ACEFDB, который отображает нисходящий поток и восходящий поток выполнения в приложении Koa.
Вы можете заметить, что он напечатан дважды. Это связано с двойным запросом, отправленным браузером для получения значка.
Совет : koa.use(function)
добавляет функцию промежуточного программного обеспечения в приложение.
В заключение
Вот и все для первой части этого учебника по генераторам JavaScript и Koa.js. Вы узнали о большинстве предпосылок, таких как генераторы, как их использовать, как использовать делегирование yield и как работает поток управления в Koa.js.
В следующей части этого руководства мы углубимся в Koa и узнаем, как создать приложение CRUD. Если у вас есть какие-либо вопросы или комментарии, не стесняйтесь связаться со мной или просто оставьте комментарий ниже.