AngularにおけるPromiseとObservableの違い
AngularにおけるPromisesとObservablesの違い
PromisesとObservablesは、JavaScriptにおける非同期処理を扱うための仕組みですが、その性質や使い方が異なります。
Promises
- 静的な値
一度生成されたPromiseの値は変更できません。 - チェーン化
Promisesは、then()
メソッドを使用して、成功または失敗の後の処理をチェーン化することができます。 - 単一の値を返す
Promisesは、非同期処理が完了したときに、成功または失敗を表す単一の値(通常は、成功の場合は値、失敗の場合はエラー)を返すことを約束します。
Observables
- 動的な値
Observablesは、新しい値が配信されるたびに、購読者に通知することができます。 - サブスクライブ
Observablesは、subscribe()
メソッドを使用して購読され、購読者が値を受け取るようになります。 - 複数の値を返す
Observablesは、時間の経過とともに複数の値を配信することができ、イベントストリームのような動作をします。
Angularにおける使用
- Observables
Angularの多くのコア機能、特にRxJSの機能を活用して、イベントストリーム、非同期処理、データフローの管理にObservablesが広く使用されています。
- Observables
複数の値を配信、購読が必要、動的な値。 - Promises
単一の値を返す、チェーン化が可能、静的な値。
PromisesとObservablesの例
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Data fetched successfully');
}, 2000);
});
}
fetchData()
.then(data => {
console.log(data ); // Output: Data fetched successfully
})
.catch(error => {
console.error(error);
});
catch()
メソッドを使用して、失敗時の処理を指定します。
import { fromEvent, interval } from 'rxjs';
// ボタンクリックイベントをObservableに変換
const buttonClick$ = fromEvent(document.getElementById('myButton'), 'click');
// 1秒ごとに値を配信するObservable
const interval$ = interval(1000);
// ボタンクリックイベントとインターバルを結合
const combined$ = buttonClick$.pipe(
switchMap(() => interval$)
);
combined$.subscribe(value => {
console.log(value);
});
subscribe()
メソッドを使用して、Observableの値を購読します。switchMap()
を使用して、ボタンクリックイベントが発生するたびに、新しいインターバルObservableを配信します。interval()
を使用して、1秒ごとに値を配信するObservableを作成します。fromEvent()
を使用して、ボタンクリックイベントをObservableに変換します。
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
impo rt { map, catchError } from 'rxjs/operators ';
@Component({
selector: 'app-my-component',
templateUrl: './my-component.html',
styleUrls: ['./my-component.css']
})
export class MyComponent implements O nInit {
data: any;
error: string;
constructor(private http: HttpClient) {}
ngOnInit() {
// Promisesを使った例
this.http.get('https://api.example.com/data')
.toPromise()
.then(data => {
this.data = data;
})
.catch(error => {
this.error = error.message;
});
// Observablesを使った例
this.http.get('https://api.example.com/data')
.pipe(
map(data => {
return data;
}),
catchError(error => {
this.error = error.message;
return of(null);
})
)
.subscribe(data => {
this.data = data;
});
}
}
- Observablesを使った例では、
pipe()
メソッドを使用して演算子をチェーンし、map()
とcatchError()
を使用してデータの変換とエラー処理を行っています。 - Promisesを使った例では、
toPromise()
メソッドを使用してPromiseに変換し、then()
とcatch()
メソッドを使用しています。
Async/Await
- Promiseベース
内部的にはPromiseを使用していますが、より直感的な書き方ができます。 - ES2017で導入された
非同期処理を同期的なコードのように記述できる構文です。
async function fetchData() {
try {
const data = await fetch('https://api.example.com/data');
const json = await data.json();
console.log(json);
} catch (error) {
console.error(error);
}
}
fetchData();
Generators
- yieldキーワード
値を返すたびに一時停止し、再開することができます。 - ES6で導入された
イテレーターを生成する関数です。
function* fetchData() {
const data = yield fetch('https://api.example.com/data');
const json = yield data.json();
return json;
}
const generator = fetchData();
generator.next().then(result => {
generator.next(result).then(result => {
console.log(result.value);
});
});
Callbacks
- 複雑な処理
複数のコールバックがネストされると、いわゆる「コールバック地獄」が発生する可能性があります。 - 伝統的な方法
非同期処理の完了時に呼び出される関数です。
function fetchData(callback) {
setTimeout(() => {
callback('Data fetched successfully');
}, 2000);
}
fetchData(data => {
console.log(data);
});
Angularにおける代替的なアプローチ
- Callbacks
Angularでは、古いコードやサードパーティライブラリとの互換性のために使用されることがあります。 - Generators
Angularでは直接使用されることは少ないですが、RxJSの内部実装で使用されています。 - Async/Await
Angularの多くの非同期操作で広く使用されています。
- Callbacks
伝統的な非同期処理の方法。 - Generators
イテレーターを生成する関数。 - Async/Await
Promiseをより直感的に扱うための構文。 - Observables
複数の値を配信するイベントストリーム。 - Promises
非同期処理の基礎となる仕組み。
angular promise rxjs