[JavaScript] Promise


JavaScriptはコールバック関数を使用して非同期処理を行います.ダイヤルバックモードは可読性が悪く,エラー処理が困難であり,一度に複数の非同期処理を処理することは限られている.
ES 6は、このようなコールバックモードの欠点を補うプロセスを導入し始めた.コールバックモードとは異なりpromisの利点は,非同期処理時点を明確に表すことができることである.

Promiseオブジェクトの作成


Promiseコンストラクション関数は、パラメータとして2つのコールバック関数、非同期処理に成功したときに呼び出されるresolve関数、および非同期処理に失敗したときに呼び出されるexecute関数を渡します.
const promise = new Promise((resolve, reject) => {
	if(/* 비동기 처리 성공 */) {
		resolve('success');
  	} else { /* 비동기 처리 실패 */
		reject('failure);
	}
});

Promiseの状態について


Promiseでの状態情報の不明な変更条件Pending非同期処理がまだ実行されていない状態作成が完了した後、デフォルト状態で非同期処理が成功した(実行済み)状態解析関数呼び出し非同期処理に失敗した状態呼び出し非同期処理失敗(実行済み)関数呼び出し拒否
完了または拒否されたステータスを固定ステータスと呼びます.固定状態とは、満たすか否かにかかわらず、非保留状態の非同期処理が行われた状態をいう.
Promiseには、処理状態と処理結果状態があります.pending状態は未定義の処理結果であり、完了状態は処理結果であり、value状態が最後の拒否状態が処理結果であり、エラーがある.

承諾の後続処理方法


Promiseの非同期処理状態が変化した場合、対応する後続処理が必要となる.このため、Promiseでは、then、catch、finallyという方法が提供されています.
Promiseの非同期処理結果に基づいて,パラメータとして後続の処理方法に渡すコールバック関数を選択的に呼び出す.このとき,Promiseの処理結果はパラメータとして後続の処理方法のコールバック関数に渡される.

  • Promise.prototype.then
    次に、メソッドは、非同期処理が成功した場合(完了状態)に呼び出された成功処理コールバック関数と、非同期処理が失敗した場合(拒否状態)に呼び出された失敗処理コールバック関数をパラメータに渡します.
    new Promise(resolve => resolve('fulfilled'))
        .then(v => console.log(v), e => console.error(e));
    new Promise((_, reject) => reject(new Error('rejected')))
        .then(v => console.log(v), e => console.error(e));

  • Promise.prototype.catch
    catchメソッドは、パラメータとしてコールバック関数を渡します.
    catchメソッドのコールバック関数はPromiseが拒否されている場合にのみ呼び出されます.
    new Promise((_, reject) => reject(new Error('rejected')))
        .catch(e => console.error(e));

  • Promise.prototype.finally
    最後に、メソッドはパラメータとしてコールバック関数を渡します.
    finallyメソッドのコールバック関数は、Promiseの処理ステータスが完了しているか拒否されているかにかかわらず、無条件に1回呼び出されます.
    new Promise(() => {})
        .finally(() => console.error('finally'));
  • Promiseでのエラー処理


    ダイヤルバックモードにはエラー処理が困難な欠点がある.Promiseはエラーを問題なく処理できます.
    非同期処理で発生したエラーを方法の2番目のコールバック関数として処理する方法がある.
    しかし,この方法の欠点は,最初のコールバック関数で発生した誤りを捕捉できず,コードが複雑になり毒性が低下することであるため,毒性が良くthen法内部で発生した誤りを捕捉できる方法を提案する.
    この方法がcatchメソッドを呼び出す方法です.すべてのthenメソッドを呼び出した後にcatchメソッドを呼び出すと、非同期処理で発生したエラーとメソッドで発生したエラーをキャッシュできます.
    promiseGet(url)
    	.then(res => console.xxx(res))  // then 메서드에서 발생한 에러도 캐치할 수 있다!
    	.catch(err => console.error(err));

    Promiseフィルタ


    コールバックモードには、コールバックhellという致命的な欠点があります.Promiseはその後catchとfinallyの後続処理法によりコールバックhellを解決した.
    Promiseは、then、catch、finallyの後続の処理方法がコールバック関数が返すPromiseを常に返すため、連続的に呼び出すことができる.これは、非同期プロセッサを追加するためにメソッドを連続的に呼び出すことができることを意味する.これをPromise Cheningと呼びます.
    PromiseはPromiseフィルタを介して非同期処理結果を受信し、後続の処理を行うため、コールバックhellは発生しません.ただし、Promiseもコールバックモードを使用しているので、コールバック関数を使用しないわけではありません.
    依然としてコールバックモードの読み取り可能性が悪い.この欠点を補うためにPromiseオブジェクトからさらにES 8までasync/awaitを導入した.async/awaitを使用すると、Promiseの後続の処理方法を必要とせずに、Promiseが同期処理とほぼ同じ処理結果を返すことができます.
    async/awaitについては、次回詳しく説明します.