- PVSM.RU - https://www.pvsm.ru -
«Next generation web framework for node.js» — так написано в документации к версии 1.0. Звучит неплохо, я к этому добавлю что 2 года назад после внедрения koa на одном из проектов у наших программистов появился термин “псевдо-синхронный код” (Это когда код выглядит как синхронный но на самом деле исполняется асинхронно). Что за бред Как это работает я расскажу под катом.
Чтоб не повторяться:
С помощью особенности работы генераторов и директивы yield мы можем асинхронно выполнить Promise или специально нами сконструированную thinkify-функцию и после выполнения промиса/функции вернуться в ту точку где вызывался yield вернуть результат и продолжить выполнение кода.
Пример такого кода:
//...
let userId = Number(this.request.userId);
let projects = yield users.getActiveProjectsByUserId(userId); // Например, обращаемся к БД
for (let project of projects) {
project.owners = yield projects.getProjectOwnersById(project.id); // Тут тоже обращаемся к БД
}
this.body = yield this.render('userProjects', projects); // Тут асихронно рендерим ответ
//...
Идея Koa идеально ложиться на парадигму микросервисов, которую я уже давно внедрил в нашей компании. Ядро фреймворка минималистично, код middleware для коа читается и понимается очень легко, что очень важно для командной разработки. Активное использоване фреймворком возможностей ES2015, минимальное травмирование психики программиста, который до этого писал на PHP (эти ребята колбеки не любят :) ).
То что было основой KoaJS, а именно библиотека co, построенная на генераторах теперь удалена из базовой реализации Koa 2.
Давайте посторим Hello world!
const Koa = require('koa');
const app = new Koa();
// response
app.use(ctx => {
ctx.body = 'Hello Koa';
});
app.listen(3000);
Как видите тут генераторов нет, но тогда как же писать расхваленый мной “псевдо-синхронный код”. В самом простом случае можно обойтись нативным кодом:
app.use((ctx, next) => {
const start = new Date();
return next().then(() => {
const ms = new Date() - start;
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});
});
next — является промисом, ctx — контекст запроса.
В таком виде без колбеков многие вещи реализовать нельзя, поэтому авторы предлагают использовать новый синкасис async/await, который еще не стал стандартом и нативно не поддерживается NodeJS но уже давно реализован в транспилере Babel. Выглядит это так
app.use(async (ctx, next) => {
const start = new Date();
await next();
const ms = new Date() - start;
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});
Также предусмотрен вариант с дополнительным подключением библиотеки co и генераторами:
app.use(co.wrap(function *(ctx, next) {
const start = new Date();
yield next();
const ms = new Date() - start;
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
}));
Когда я говорил о “выпиленных” генераторах, то был не совсем точен. Для совместимости, если вы оформите middleware в стиле koa 1.0, koa 2.0 его подключит и исполнит он при этом в консоли будет “Koa deprecated Support for generators will been removed in v3…” Другими словами до версии 3.x все будет работать.
Вот пример:
// Koa will convert
app.use(function *(next) {
const start = new Date();
yield next;
const ms = new Date() - start;
console.log(`${this.method} ${this.url} - ${ms}ms`);
});
Также можно сконвертировать существующий middleware в формат 2.0 самостоятельно с помощью модуля koa-convert
const convert = require('koa-convert');
app.use(convert(function *(next) {
const start = new Date();
yield next;
const ms = new Date() - start;
console.log(`${this.method} ${this.url} - ${ms}ms`);
}));
В этом случае никаких предупреждений на консоль, поэтому я рекомендую использовать именно такой способ подключения legacy middleware.
Конечно я не могу утверждать на 100%, но полгода стабильной работы одного из типовых сервисов дают мне уверенность в том что 2.0 достаточно стабилен.
Я хочу иметь право выбора каким способом реализовывать свой middleware. Koa 2.0 дает мне три пути: нативный, генераторы и async/await
Koa 2.0 уже поддерживают многие популярные middleware, а если не поддерживают, то работают через koa-convert
Если вы сейчас приглядываетесь к новым фреймворкам, попробуйте что-то небольшое закодить на Koa — уверен, Вы не пожалеете что потратите на это время.
Автор: apelsyn
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/node-js/121084
Ссылки в тексте:
[1] Знакомство с Koa или coroutine в nodejs: https://habrahabr.ru/post/238095/
[2] Генераторы в ES6 и асинхронный код по-новому: https://habrahabr.ru/post/277033/
[3] Документация по Koa 1.x: http://koajs.com/
[4] Примеры на Koa 2.x: https://github.com/koajs/koa/tree/v2.x
[5] Middleware для Koa: https://github.com/koajs/koa/wiki
[6] Примеры небольших приложений на Koa: https://github.com/koajs/examples
[7] Мой скелет REST-сервиса на Koa 2.0: https://github.com/ria-com/node-koajs-rest-skeleton/tree/v2.x
[8] Скелет приложения на Koa2: https://github.com/17koa/koa2-demo
[9] Шаблон для Koa2 c настроеным Babel: https://github.com/geekplux/koa2-boilerplate
[10] Источник: https://habrahabr.ru/post/301126/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.