孤独プログラマー譚

孤独死が近い。

RxJS Subject

Subjectは、Observable + Observer である。
Subjectはユニキャストできる。
Subjectは、Subjectオブジェクト作成後、後々ストリームを流せる。
Observableオブジェクトより、使い勝手が良さそう?

let sbj = new Subject

sbj.subscribe((val) => console.log(val))
sbj.subscribe((val) => console.log(val * 10))

sbj.next(1) // 1, 10
sbj.next(2) // 2, 20
sbj.next(3) // 3, 30

RxJS tap

前回と同じ、こちら共通関数。

function sto(x, time = 1000)  {
  const observable = new Observable(subscriber => {
    setTimeout(() => {
      subscriber.next(x)
      subscriber.complete()
    }, time);
  });
  return observable
}

function cl(x) {
  console.log(x)
}



副作用のある処理は、tapに書く。
パッと見で、とても分かりやすい。

let obs = sto(1)
let meta = 'foo'

obs.pipe(
  tap(() => {
    cl(meta) // 'foo'
    meta = 'bar'
  })
)
.subscribe(() => {
  cl(meta) // 'bar'
})

RxJS mergeMap, concatMap, switchMapの違い

以下、共通関数。

function sto(x, time = 1000)  {
  const observable = new Observable(subscriber => {
    setTimeout(() => {
      subscriber.next(x)
      subscriber.complete()
    }, time);
  });
  return observable
}

function cl(x) {
  console.log(x)
}


  • mergeMap
of(0, 1, 2).pipe(
  mergeMap(x => sto(x + 1, 1000))
)
.subscribe(cl)

1,2,3 と同時に表示される。

  • concatMap
of(0, 1, 2).pipe(
  concatMap(x => sto(x + 1, 1000))
)
.subscribe(cl)

1,2,3 と1秒間隔で表示される。

  • switchMap
of(0, 1, 2).pipe(
  switchMap(x => sto(x + 1, 1000))
)
.subscribe(cl)

3 と表示される。
1,2 はキャンセルされる。

Observable resolveする方法

Promiseのresolve( )に該当するのが、Observableのnext( )になる。

Observable.create((observer) => {
  setTimeout(() => {
    observer.next(1)
  }, 1000)
})
.pipe(
  map(val => Number(val) + 2),
  map(val => Number(val) * 3),
)
.subscribe(val => {
  console.log(val) // 1秒後に"9"
})

Angular Observable, Promiseの相互変換

ObservableもPromiseも、似たようなもんだと思ってます。

import { from as fromPromise } from 'rxjs';

const foo = this.http.get('http://localhost:3000/')
console.log(foo) // Observable
foo.subscribe(res => console.log(1, res))

const bar = foo.toPromise()
console.log(bar) // Promise
bar.then(res => console.log(2, res))

const baz = fromPromise(bar)
console.log(baz) // Observable
baz.subscribe(res => console.log(3, res))

test

" copy file path
command! -nargs=0 CopyFilePath call s:Clip(expand('%:p'))
nnoremap <space>f :CopyFilePath<CR>
command! -nargs=0 CopyDirPath call s:Clip(expand('%:p:h'))
nnoremap <space>d :CopyDirPath<CR>
command! -nargs=0 CopyCwd call s:Clip(getcwd())
nnoremap <space>c :CopyCwd<CR>
nnoremap <space>m :cd %:h<CR>:echo "CWD => " . getcwd()<CR>
function! s:Clip(data)
  let @*=a:data
  echo "clipped: " . a:data
endfunction

Promise then, catchの連結

以下のコードは、どのような出力になるか?

const promise = Promise.reject()
promise
.then(() => console.log(1))
.catch(() => console.log(2))
.then(() => console.log(3))
.catch(() => console.log(4))
.then(() => console.log(5))
.catch(() => console.log(6))


答えは「2, 3, 5」

初めの変数promiseは、rejectされたPromiseオブジェクト。
1のthenは、rejectされたPromiseオブジェクトだから通らない。
2のcatchは、rejectされたPromiseオブジェクトだから通る。
同時にreturnされたと見なされ、resolveされたPromiseオブジェクトが返却される。
3のthenは、resolveされたPromiseオブジェクトだから通る。
同時にreturnされたと見なされ、resolveされたPromiseオブジェクトが返却される。
4のcatchは、resolveされたPromiseオブジェクトだから通らない。
5のthenは、resolveされたPromiseオブジェクトだから通る。
同時にreturnされたと見なされ、resolveされたPromiseオブジェクトが返却される。
6のcatchは、resolveされたPromiseオブジェクトだから通らない。