Promiseオブジェクトのメソッド(all、race)を試す
前回の続きでPromiseオブジェクトのallとraceを試したコードです。
allとraceの動きを確認するためにまずは次の2つの関数を用意しました。
- resolveAsync - 指定した時間後にresolveするPromiseを返す関数
- rejectAsync - 指定した時間後にrejectするPromiseを返す関数
話は少しそれますが、ログで時間を確認するためにConsole.timeStampメソッドを使っています。私の環境では最初TS2339 (TS) プロパティ 'timeStamp' は型 'Console' に存在しません。
といったエラーが出ていましたが、ConsoleのインターフェイスにtimeStampメソッドを定義してエラーを解消しました。
interface Console { timeStamp(label?: string): void; }
Declaration Mergingという機能ですね。たぶん。
Declaration Merging · TypeScript
脱線終わり。
Promise.all
Promise.allメソッドは、引数のすべてのPromiseがresolveするとresolveするか、引数のPromiseのどれか1つでもrejectするとrejectするPromiseを返します。
Promise.all() - JavaScript | MDN
resolveする場合
Promise.allメソッド(とawait)は、引数のすべてのPromiseがresolveするまで待った後、引数のPromiseそれぞれの結果を配列として取得できます。以下では3秒待って、3つのPromiseの結果を取得しています。
rejectする場合
引数のPromiseのうちどれか1つがrejectするとすぐに例外がスローされます。以下は1秒後に"エラー2"がrejectしています。
Promise.race
Promise.raceメソッドは、引数のPromiseのどれか1つがresolveするとresolveするか、引数のPromiseのどれか1つがrejectするとrejectするPromiseを返します。
resolveする場合
引数のPromiseのうちどれか1つがresolveするとすぐにresolveしたPromiseの結果を返します。1秒後に"c"がresolveされています。
rejectする場合
引数のPromiseのうちどれか1つがrejectするとすぐに例外がスローされます。1秒後に"エラー2"がrejectしています。
おしまい。
Promiseオブジェクトのメソッド(resolve、reject)を試す
Promiseオブジェクトのスタティックなメソッドを使ったサンプルです。async/awaitを試してみたくなったということもあってコードを書いてみました。
Promiseオブジェクトのスタティックなメソッドは4つ。
- Promise.resolve
- Promise.reject
- Promise.all
- Promise.race
今回はそのうちresolve、rejectを確認しました。以下はTypeScriptのコードです。結果はEdgeで確認しています。
Promise.resolve
まずはresolveした(完了した、成功した)Promiseを返すresolveメソッドです。
引数に渡した値でresolveします。実行結果からもわかりますが、デバッグ実行するとawaitのタイミングで一度関数を抜けます。
Promise.reject
rejectメソッドはrejectした(失敗した)Promiseを返します。
引数に渡した値が例外としてスローされます。
残りのallとraceは次回で。
RxJS - doオペレータ
公式ドキュメントに「デバッグするときに便利だよ」と書いてあるdoオペレータを試しました。
This operator is useful for debugging your Observables for the correct values or performing other side effects.
こちらのドキュメントのdoオペレータの説明から引用してます。(ハッシュ付きのリンクを埋めてるのにジャンプしないけど気にしない・・・)
doオペレータを使ってトレース
doオペレータを使うと値がどのように流れているか確認できます。
次にコードでは、
- 値"1"と"3"はfilterで止まっている
- 値"2"はfilter、mapと処理されてsubscribeでnextコールバックが呼ばれている
といったことが読み取れると思います。
またdoオペレータの引数はsubscribeと同じでcompleteコールバックやerrorコールバックも指定できます。
RxJS - scanオペレータとreduceオペレータ
scanオペレータが気になって試しました。scanオペレータはreduceオペレータと似ています。比較しながら確認したコードを残しておきます。
違いその1
- scanは都度nextコールバックが呼ばれる
- reduceは(completeする前に)1回だけnextコールバックが呼ばれる
違いその2
- scanはcompleteしなくてもnextコールバックが呼ばれる
- reduceはcompleteしない限りnextコールバックが呼ばれない
ASP.NET CoreでTypeScriptとwebpackとRxJS
前回の続きでもう少しします。ASP.NET Core + TypeScript + webpackの環境にRxJSを導入してみます。
実のところ前回のエントリはTypeScriptでRxJSを試したくなったのがきっかけで、今回が本当の目的だったりします。
npmでRxJSをインストール
まずnpmを使ってRxJSをインストールしましょう。package.jsonで@reactivex/rxjs
をインストールするように指定します。
{ "version": "1.0.0", "name": "asp.net", "private": true, "dependencies": { "@reactivex/rxjs": "5.5.6" }, "devDependencies": { "webpack": "3.10.0", "typescript": "2.6.2", "ts-loader": "3.2.0" } }
app.tsを書き換える
app.tsでRx.ObservableクラスをインポートしてRxJSを試すコードを書きます。
// app.ts // Rx.Observableをインポート import { Observable } from "@reactivex/rxjs"; // lib.tsのGreeterクラスをインポート import { Greeter } from "./lib"; // あいさつする Observable.of("world") .subscribe(message => alert(Greeter.greet(message)));
モジュールをインポートするには、モジュール名だけを指定する方法とパスを指定する方法があるみたいです。
tsconfig.jsを修正する
このままではビルドエラーになるので、tsconfig.jsを修正しましょう。コンパイラがnode_modulesフォルダ内のライブラリを参照できるように、"moduleResolution": "node"
を追記しています。またRxJSがES2015の機能を使っているようなので、"lib": [ "es5", "es2015", "dom" ]
も追記しています。
{ "compileOnSave": true, "compilerOptions": { "noImplicitAny": false, "noEmitOnError": true, "removeComments": false, "sourceMap": true, "target": "es5", "module": "es2015", // コンパイラが"node_modules"フォルダを参照するみたい "moduleResolution": "node", // RxJSで"es2015"を利用しているみたい "lib": [ "es5", "es2015", "dom" ] }, "exclude": [ "node_modules", "wwwroot" ] }
これでビルドが通るはず。デバッグ実行して世界にあいさつしましょう。まだまだわからないことばかりですが、とりあえずRxJSを試せる環境になったので目標達成です。