Promise 非同期メソッドの結果で処理を分岐
よくあるのが、オブジェクトをresolveし、その中に分岐用のフラグを含める。
まったく美しくない。見ててつらい。
const confess = (iLoveMai) => { console.log(iLoveMai ? '私は白石麻衣を愛しています。' : '私は白石麻衣を愛していません。' ) } const { love: iLoveMai1 } = await Promise.resolve({ love: true }) confess(iLoveMai1) // 私は白石麻衣を愛しています。 const { love: iLoveMai2 } = await Promise.resolve({ love: false }) confess(iLoveMai2) // 私は白石麻衣を愛していません。
resolve, reject で分岐させる。
オブジェクトにフラグを持たせる必要がない。
シンプルで分かりやすい。良い!
const iLoveMai3 = await Promise.resolve().then(() => true) confess(iLoveMai3) // 私は白石麻衣を愛しています。 const iLoveMai4 = await Promise.reject().catch(() => false) confess(iLoveMai4) // 私は白石麻衣を愛していません。
Promise catch()からthen()への復帰
catch()からthen()へ。
そして、then()からcatch()へ。
const promise = Promise.resolve() promise .then(() => { console.log(1) throw new Error() }) .catch(() => { console.log(2) return }) .then(() => { console.log(3) throw new Error() }) .catch(() => { console.log(4) return }) // 1 2 3 4
以下のようにも、書き換えられる。
promise .then(() => { console.log(1) return Promise.reject(new Error()) }) .catch(() => { console.log(2) return Promise.resolve() }) .then(() => { console.log(3) return Promise.reject(new Error()) }) .catch(() => { console.log(4) return Promise.resolve() }) // 1 2 3 4
Promise reject と catch
以下の2つは、書き換えられる。
const foo = () => { return new Promise((resolve, reject) => reject(new Error('foo_value'))) } const bar = async () => { throw new Error('bar_value') }
catchで受ける。
foo().catch((err) => console.log(err.message)) // foo_value bar().catch((err) => console.log(err.message)) // bar_value
resolve = async + return
reject = async + throw
という解釈でいいと思う。
JavaScript Promise.thenメソッドの返却値
asyncメソッドと似たような考え方でいいと思う。
const promise = new Promise(resolve => resolve()) const foo = promise.then(async () => { await new Promise(resolve => { setTimeout(resolve, 1000) }) return 'foo_value' }) const bar = promise.then(() => { return new Promise(resolve => { setTimeout(() => { resolve('bar_value') }, 2000) }) }) foo.then((res) => console.log(res)) // 1秒後にfoo_value bar.then((res) => console.log(res)) // 2秒後にbar_value
Promiseオブジェクトをreturnすると、そのままそのPromiseオブジェクトがthen()の返却値となる。
Promiseオブジェクト以外をreturnすると、Promiseでラッピングされて返却される。
JavaScript Promiseとasyncの書き換え
以下の2つ、Promiseとasyncメソッドは書き換えられる。
foo() { return new Promise((resolve) => { setTimeout(() => { resolve('foo_value') }, 1000) }) }
async bar() { await new Promise((resolve) => { setTimeout(resolve, 1000) }) return 'bar_value' }
メソッドから返却されたPromiseオブジェクトはawaitできる。
asyncメソッドの返却値もPromiseオブジェクトとなる。
const val1 = await this.foo() console.log(val1) // foo_value const val2 = await this.bar() console.log(val2) // bar_value
awaitでなく、then()メソッドでも対応できる。
asyncメソッドの返却値(Promiseオブジェクト)からthen()メソッドを使用することもできる。
const promise1 = this.foo() promise1.then(val => console.log(val)) // foo_value const promise2 = this.bar() promise2.then(val => console.log(val)) // bar_value
Angular ルーティング
ルーティングの最低限の構成。
/* app-routing.module.ts */ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { FooComponent } from './foo/foo.component'; const routes: Routes = [ { path: 'foo', component: FooComponent } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
router-outlet の部分に出力される。
<!-- app.component.html --> <router-outlet></router-outlet>
Angular FormControl
FormGroup を使わないパターン。
export class AppComponent { foo = new FormControl('foo-desu', [ Validators.required, ]) }
<input [formControl]="foo"> <div>value: {{foo.value}}</div> <div>error: {{foo.errors | json}}</div>
FormGroup を使うパターン。
export class AppComponent { constructor(private builder: FormBuilder) {} foo = new FormControl('foo-desu', [ Validators.required, ]) metaForm = this.builder.group({ foo: this.foo }) }
<form [formGroup]="metaForm"> <input [formControl]="foo"> <div>input_value: {{foo.value}}</div> <div>input_error: {{foo.errors | json}}</div> <div>form_value: {{metaForm.controls.foo.value}}</div> <div>form_error: {{metaForm.controls.foo.errors | json}}</div> </form>