기본 콘텐츠로 건너뛰기

라벨이 RxJS인 게시물 표시

decaffeinate hack - Rx.js 를 import 해보자!

http://decaffeinate-project.org/repl 평소에 coffee를 좋아하지만 ecma6로 바꿔서 보여줘야 좋아하는 분들이 종종 있어서 decaffeinate를 쓰다보니 나름 console.log 만 띡 나오는게 꽤 쓰기 좋아서 자주 쓰는데. 쓰다보니 아쉬운 점이 외부 라이브러리를 불러올 수가 없어서 약간의 hack을 해보기로 했다. script = document.createElement('script') script.src = "//cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.0-rc.2/Rx.js" x=document.getElementsByTagName('script')[0] x.parentNode.insertBefore script, x 단순하게 생각하면 이런 식 script tag을 하나 만들고 src를 Rx.js CDN 라이브러리로 지정하고 insertBefore를 사용해서 밀어넣으면 될거라고 생각했는데 repl.js?t=2015-03-09T08:30:22-07:00:7 Uncaught Error: module is not supported in the browser, you need a commonjs environment such as node.js/io.js, browserify/webpack etc 이런 오류가 난다. 보니까 의도적으로 decaffeinate에서 "module", "exports", "require" 이라는 말을 쓰면 저지하도록 되있더라   ["module", "exports", "require"].forEach(function(commonVar){     Object.defineProperty(window, commonVar, {       get: function () {         throw n...

RxJS - ReactiveX 인터뷰

A: 왜 RxJS입니까 B: javascript는 참 쉽고 친숙한 언어죠. A: 별로 그렇게 생각 안합니다만. B: 그래서 좀 어렵고 있어보이는게 뭘까 싶어서... A: 네? B: 함수형이라는게 유행하기도 하고 f(x) 좋쟎습니까? 미스테리~ 미스테리~ 정수정짱짱 으아아 이런 수학선생님이라면 수포자 따윈 A: ... B: 그리고 반응형이라는 말 뭔가 A: 뭔가? B: 대충대충해도 막 알아서 할거 같고... A: 그럴리가요? B: 안그렇겠죠? A: 네 B: 네 (잠시만 기다려주세요) A: 그래도 뭔가 매력이 있으니 이렇게 시간을 내셔서 이것저것 Rx에 대해 글도 쓰고 이야기도 하고 그러시는거 아닌가요? B: 매력이라. 으음. 제가 팔꿈치 터널 증후근이 좀 있어요. 오른손 세끼손가락, 약지손가락이 저립니다. A: 무슨 상관이? B: 그래서 각종 괄호를 쓰는게 너무 힘듭니다. 소중대괄호 만든 사람 죽었으면. Hello world (ASCII): https://esolangs.org/wiki/Parenthesis_Hell A: 이미 옛날에 돌아가셨겠죠. B: 그렇겠네요. 아무튼 그래서 소중대괄호 의존이 적은 커피스크립트를 쓰는데요. A: 빨리 본론을 말씀해주시죠. B: 커피스크립트에서 가로로 80자 이상쓰면 Line exceeds maximum allowed length 라고 경고해요. A: 그래서요? B: 근데 Rx를 쓰면 코드를 가늘게 쓸 수가 있더라구요. A: 호오? B: 그리고 = 쓰는 것도 너무 힘듭니다. A: 네? B: 오른손을 쓰쟎아요. A: ... 그러니까 정리하면 1. 괄호가 힘들다 2. 커피를 쓴다 3. 커피는 길게 쓰면 경고 4. Rx를 쓰면 코드가 가늘다 5. 대입문을 줄이고 싶다. B: 네 하지만 5번은 생각보다 별로... A: B: B: 아! A: ? B: 코드가 가늘어서 좋은 점이. A: 네. B: 핸드폰에서 코드를 보...

RxJS 에서 requestAnimationFrame 을 사용하려면?

http://jsbin.com/qosigic/edit?html,js,output 소스는 이쪽. 게임과 같은 분야는 타이밍 처리가 매우 중요하기 때문에 UI를 갱신하는 무한 루프를 놓고 delta 시간을 얻어와서 처리하는 로직을 많이 쓰는데 이걸 Javascript 에서 할 땐 전통적으로 setTimeout 을 걸어놓은 함수를 재귀하는 식으로 썼는데 문제는 setTimeout(setInterval도 마찬가지)이 굉장히 부정확한 타이밍을 가지고 있었고 이를 보완하기 위해 requestAnimationFrame 이라는 것을 만들어 사용하기 시작했다. 문제는 역시 지원하지 않는 몇몇 브라우저(ex. IE < 10)들 때문에 안타깝게도 RxJS 5.x 의 defaultScheduler에선 setTimeout( https://github.com/Reactive-Extensions/RxJS/blob/6dac0365ad22f87a92197fc4dcee70e72a11ddbb/src/modular/scheduler/defaultscheduler.js#L119 )을 쓰고 있는데 물론 권장하는 방식은  https://github.com/Reactive-Extensions/RxJS/tree/8fa95ac884181fb6cbff8ce7c1d669ffb190f5e4/examples/crop  의 예처럼 RequestAnimationFrameScheduler 를 사용하는 것이지만 RxLua 처럼 기본으로 타이머가 없고 외부패키지에 의존하는 환경도 있고해서 기본 RxJS 환경에서 직접 만들어보기로 했다. Scope 을 위해 일단 function으로 감싸보았다. (function() {   var canvas=document.getElementById('canvas1');   var ctx = canvas.getContext('2d');   var start = 0;   var step = functi...

RxJS Basic - 기초

http://reactivex.io/rxjs/manual/tutorial.html  글을 대충 번역해서 쓰는 글입니다. jsbin/codepen 같은 곳에서 RxJS 라이브러리를 추가한 후 연습해봅시다. 현재 가장 최근 버전은  https://cdnjs.com/libraries/rxjs/5.0.0-rc.1  에서 확인하세요. Observable 로 변환하기 하나 혹은 n 개의 값으로부터 Rx.Observable.of('foo', 'bar'); =>foo =>bar 배열로부터 Rx.Observable.from([1,2,3]); =>1 =>2 =>3 이벤트로부터 Rx.Observable.fromEvent(document.querySelector('button'), 'click'); =>button을 누를 때 마다 event로 변환 Promise로부터 Rx.Observable.fromPromise(fetch('/users')); =>/user 주소의 내용을 fetch한 것을 변환 마지막 인자가 콜백인 경우 콜백으로부터 /* node.js */ var exists = Rx.Observable.bindCallback(fs.exists); exists('file.txt').subscribe(exists => console.log('Does file exist?', exists)); var rename = Rx.Observable.bindNodeCallback(fs.rename); rename('file.txt', 'else.txt').subscribe(() => console.log('Renamed!')); Observable 만들기 외부로부터 새로운 이벤트를 생성한다. var myObservable = Rx.Subject.create(); myObserv...

amok.js 에서 RxJS와 coffeescript 사용하기

amok은 live reload 가 가능해서 개발을 즐겁게 한다. 프로토타이핑할때 아주 좋다. RxJS 라이브러리를 받고 index.js 도 만들자. curl https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.0-beta.12/Rx.min.js > Rx.min.js touch index.js index.coffee package.json 을 만들어 놓으면 편하다. npm init 을 해서 엔터 연타하고 script 부분만 수정하자 {   "name": "rxamok",   "version": "1.0.0",   "description": "",   "main": "index.js",   "scripts": {     "start": "amok --browser chrome --interactive --hot Rx.min.js index.js"   },   "author": "",   "license": "ISC" } 이러면 준비 끝. amok 에서 coffeescript를 compile 하는 옵션이 deprecated 되었다고 한다. 하지만 걱정할 것 없다. 저장할때마다 자동으로 coffeescript를 컴파일 할 수 있다. coffee -wco ./ *.coffee 해놓고 편하게 코딩하자. rate = 1000/60 c = document.createElement 'canvas' c.style.position = 'absolute' c.style.top = '0' c.style.left = '0' resize = ->   c.width = w...

RxJS 에서 GameScene 을 구현하고 있다.

결과물은 여기에 http://jsbin.com/wuhega/edit?js,output Reactive Programming 의 장점+효용이 극대화되는 분야는 아무래도 게임이지 않을까 싶어서 짬을 내어 RxJS로 슈팅게임을 만들고 있다. 배경+플레이어+총알:  https://jsbin.com/worewow/edit?js,output 1+적+폭파에니메이션:  https://jsbin.com/modedic/edit?js,output 2+coffee+적 움직임등 :  https://jsbin.com/yobuka/ 대략, 이런 흐름으로 살을 조금씩 붙여가면서 올리고 있는데 어느정도 튜토리얼을 만들려는 생각으로 ECMA6를 가지고 시작을 했지만 {}, (), [] 괄호노동을 통한 손목터널증후근과 코딩하는 시간 만큼 쌍 맞추는 시간이 소모되는 자신을 발견하고 개인의 행복을 위해(...) 다시 coffeescript로 바꿔서 진행하고 있다. 살 것 같다. 아효. 아마도 곧 합쳐질 것 같지만 어느정도 내용물이 만들어졌으니 이것들을 감싸는 껍데기를 어떻게 만들지 코드를 짜면서 고민해보았다. 일단 크게 나누어 보기를 Splash Scene - 한번만 노출. 게임명과 제작자에 대해 알리는 화면 Title Scene - 게임시작을 위해 대기하는 화면 Game Scene - 실제 게임 화면 GameOver Scene - 게임을 더 이상할 수 없는 상황. 이정도로 잡고 1>2>3>4>2>... 의 반복 구조로 설계를 해보기로 했다. 아무런 레퍼런스도 없고 검색해 본 것도 없어서 매우 삽질이 예상되지만 그래도 FRP(Functional Reactive Programming)원칙에 충실하려고 노력했다. 먼저, 화면을 준비한다. 'use strict' ### setup canvas ### c = document.createElement 'canvas' ...

Rx 에서 drag and drop 구현.

http://jsbin.com/geqige/edit?js,console,output 선 소스. ( 조금 더 자세한 구현 :  http://jsbin.com/ziraga/edit?html,js,output ) 먼저 Drag and Drop이라는게 어떤 절차인지 생각해보면 이동하고자 하는 대상에 MouseDown 이동하고자 하는 지점까지 MouseMove 이동하고자 하는 지점에서 MouseUp 하는 세개의 동작을 순서대로 실행하는 것이라 할 수 있겠다. 100,100 위치에 있는 A라는 대상을 200,200까지 Drag and Drop을 하는 과정을 표로 옮기면 시간(seq) 행동 좌표 1 mousedown (150,150) 2 mousemove (150,150) 3 mousemove (160,160) 4 mousemove (170,170) 5 mousemove (..., ...) (n-1)th mousemove (250, 250) (n)th mouseup (250, 250) 과 같은 과정을 수행할 것이다. 눈치챘을지도 모르겠지만 mousemove 구간이 바로 Stream이다! Rx 기준으로 그러면 다시 Drag and Drop을 재정의하면 mousedown 이후 시점으로부터 mouseup이 되기전까지 mousemove 를 Observe 하는 것 인것이다. 그러면 재료를 모아보자. mousedown mouseup mousemove 이 세 개를 Observable 로 만들자.   const down$ = Rx.Observable.fromEvent(box, 'mousedown');   const...

RxJS 연습.

http://jsbin.com/roweju  에 해보고 있음. Rx.Observable 에 fromEvent 를 붙여서 click 눌렀을 때 카운트가 올라가는 건 솔직히 잘 모르겠고 map으로 가공하고 최종결과를 subscribe 하는 패턴은 재미있다. 비동기 실행을 하는 부분은  Rx.Observable.create (observer)-> 로 시작해서 observer.next( 리턴값 ) 형식으로 끝나는 건 promise 랑 되게 비슷한 패턴이다. .flatMap은    .map (url)-> sendRequest url, 'GET', null    .mergeAll() 이 두개를 합친 것이라고 보면 됨. * HTML <!DOCTYPE html> <html> <head> <script src="https://npmcdn.com/@reactivex/rxjs@5.0.0-beta.7/dist/global/Rx.umd.js"></script>   <meta charset="utf-8">   <meta name="viewport" content="width=device-width">   <title>JS Bin</title> </head> <body>   <button id="btn">click</button>   <p><span id="counter">1</span>th click</p>   <button id="btn-get">get posts</button>   <pre id="result">   </pre> </b...