Nov. 13th, 2014

ermouth: (ang)

server-emulationПридумалась тут на днях офигенная концепция как на клиенте, в браузере, разрабатывать и отлаживать серверный js-код, работающий с БД. Из картиночки справа в общем всё понятно.

В нашем типичном стеке серверных технологий – node.js + express + cradle + CouchDB – достаточно заменить только cradle.js на PouchDB.

Обвес, позволяющий проделывать весь этот трюк в браузере, оказался на удивление несложным в целом. Я его как proof of concept написал за вечер, а на следующий вечер у меня уже заработал серверный код, полностью написанный в нашей самопальной IDE.

Как ни странно, всё взлетело сразу почти, без особого бубна с функционалом БД. Споткнулся я сначала на криптографии, но это мы проработали прошлой зимой, оставалось только чуток подкрутить. Гораздо более серьёзным оказался затык на библиотеке, обеспечивающий Promise-функционал нужного синтаксиса.

Промисы – модная и очень удобная штука, мы активно используем. Коллбэки – фу, промисы – кул. Беда в том, что синтаксис промисов иногда существенно отличается от библиотеки к библиотеке, там нет единого стандарта.

Исторически так сложилось, что на клиенте мы используем модель jQuery.Deferred – которая не очень то удачна, по-честному. Ну и оказалось что для node.js нет либы, которая повторяла бы синтаксис $.Deferred – чему я был очень удивлён.

В результате перебора bluebird.js, затем lie.js [ага, var Promise = require("lie")] и затем Q.js оказалось, что проще всего имитировать $.Deferred под нодом с помощью Q. Ну, как известно “то, что вы ищете, вы найдёте в самом последнем месте”, да.

Так вот, в самом простейшем варианте код выделки симулякра $.Deferred из Q.defer умещается в 20 строк:


var Q = require("q");
var Promise = function(){
 var q = Q.defer(),
 qp = q.promise,
 pi = {
  then:function(a,b){return qp.then(a,b);},
  fail:function(a,b){return qp.fail(a,b);},
  done:function(a,b){return qp.done(a,b);},
  progress:function(a,b){return qp.progress(a,b);},
  promise: function(){return q.promise;},
  resolve:function(a,b){q.resolve(a,b); return pi;},
  reject:function(a,b){q.reject(a,b); return pi;},
  notify:function(a,b){q.notify(a,b); return pi;},
  isResolved:function(a,b){return q.isFulfilled(a,b);},
  isRejected:function(a,b){return q.isRejected(a,b);},
  state: function(){ 
   var state = qp.inspect().state;
   return state==="fulfilled"?"resolved":state;
  }
 };
 return pi;
}


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

Сегодня кста выяснилось, что node.js даже последних сборок использует уже не поддерживаемую Гуглом версию V8. А нод много где в продакшене используется о_О

Profile

ermouth: (Default)
ermouth

November 2021

S M T W T F S
 123456
78910111213
14151617181920
21 222324252627
282930    

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated May. 30th, 2025 11:33 am
Powered by Dreamwidth Studios