Pull to refresh

TameJS — приручаем асинхронное программирование

Reading time 3 min
Views 2.5K

Что такое TameJS ?


TameJS — это расширение Javascript, которое делает событийное/асинхронное программирование более простым и элегантным. Его очень просто использовать с nodejs или другими v8-проектами.

Простой пример


Допустим, у нас есть сайт знакомств, и мы хотим написать обработчик посещения пользователем «Angel» страницы пользователя «Buffy».

Алгоритм такого визита следующий:
  • высчитать рейтинг(score), насколько Buffy подходит Angel (общие интересы и предпочтения)
  • найти следующую пару для Angel
  • отметить посещение, записать время визита
  • послать Buffy уведомление о посещении, только если — 1) рейтинг сходства высок и 2) пользователи не посещали страницы друг друга


При линейном программировании, код выглядел бы так:
handleVisit : function(angel, buffy) {
	var match_score = getScore(angel, buffy);
	var next_match  = getNextMatch(angel);
	var visit_info  = recordVisitAndGetInfo(angel, buffy);
	if (match_score > 0.9 && ! visit_info.last_visit) {
		sendVisitorEmail(angel, buffy);
	}
	doSomeFinalThings(match_score, next_match, visit_info);
}


Это выглядит наглядно, однако нам необходимо использовать асинхронное программирование, и код становится таким:
handleVisit : function(angel, buffy) {
  getScore(angel, buffy, function(match_score) {
    getNextMatch(angel, function(next_match) {
      recordVisitAndGetInfo(angel, buffy, function(visit_info) {
        if (match_score > 0.9 && ! visit_info.last_visit) {
          sendVisitorEmail(angel, buffy);
        }
        doSomeFinalThings(match_score, next_match, visit_info);
      });
    });
  });
}


Теперь код правильный, асинхронный, не содержит блокирующих вызовов, но читать его стало заметно сложнее для, например, стороннего программиста.
Также, мы можем заметить, что в нашем коде вызовы функций getScore, getNextMatch и recordVisitAndGetInfo не зависят друг от друга и могли бы выполняться параллельно.
Чем же нам поможет TameJS?

C TameJS код будет выглядеть следующим образом:
handleVisit : function(angel, buffy) {
	await {
		getScore (angel, buffy, defer(var score));
		getNextMatch (angel, buffy, defer(var next));
		recordVisitAndGetInfo (angel, buffy, defer(var vinfo));
	}
	if (score > 0.9 && ! vinfo.last_visit) {
		sendVisitorEmail(angel, buffy);
	}
	doSomeFinalThings(score, next, vinfo);
}


Код стал наглядным, читаемым, и при этом он полностью асинхронный и выполняется быстрее, чем предыдущий асинхронный вариант за счет параллельного исполнения getScore, getNextMatch и recordVisitAndGetInfo!

Вам понравилось также, как и мне?

Установка TameJS



Установка в Node.JS делается через пакетный менеджер npm:
npm install -g tamejs


И далее в коде регистрируем расширение языка:
require ('tamejs').register (); // register the *.tjs suffix
require ("mylib.tjs");          // then use node.js's import as normal


Вот и все! Далее, Tame сам компилирует tjs файлы в нативный JS.

Как работает TameJS


Синтаксический сахар TameJS заключен всего в двух, совместно используемых, ключевых словах await и defer

var res1, res2;
await {
	doOneThing(defer(res1));
	andAnother(defer(res2));
}
thenDoSomethingWith(res1, res2);


Блок await помечает секцию кода, содержащую внешние события, например, общение с сетью или работа с диском, или таймер. В блоке await содержится несколько defer. Прохождение блока await завершается только после выполнения всех defer в блоке. defer() возвращает анонимную функцию, которую нужно использовать как callback для асинхронных вызовов. Если ваши callback функции предполагают наличие аргументов, укажите этот набор аргументов в defer(). Эти результаты будут доступны после завершения блока await.

Об авторах


TameJS разработан OkCupid и распространяется по лицензии MIT. Есть репозиторий в github, проект молодой, активность в проекте присутствует.
Сайт проекта — tamejs.org

Альтернативы


Если вас заинтересовали расширения, влияющие на поток команд, рекомендуется обратить внимание также на StratifiedJS, Step и Seq.
Tags:
Hubs:
+74
Comments 32
Comments Comments 32

Articles