[深い]プロミス
13305 ワード
保証する
JavaScriptはコールバック関数を非同期処理の1つのモードとして使用する
=>ダイヤルバックhellの読み取りが悪く、非同期処理中に発生したエラーは処理しにくく、1回に複数の非同期処理を処理するのも限られている
ES 6は、非同期処理の別のモードとして프로미스
を採用する.
非同期コールバックモードの欠点
비동기 함수
は、関数の内部で非同期に実行されるコードを含む関数です.非同期関数の非同期コードは、非同期関数が終了した後に完了します.
=>非同期関数の内部で非同期で実行されているコードで処理結果を外部に戻すか、親ミラー変数に処理結果を割り当てると、予想通りに実行されません.
=>非同期関数は、非同期処理結果を外部に戻すことはできません.親ミラーの変数に割り当てることもできません.
したがって,非同期関数の処理結果を非同期関数内部で後続処理する必要がある.通常、非同期関数にコールバック関数を提供し、非同期処理が成功した場合にコールバック関数を呼び出し、非同期処理が失敗した場合にコールバック関数を呼び出すために、非同期処理結果の後続処理を実行します.
しかし,この方式はコールバック関数呼び出しが重なるため,より複雑度の高いコールバックhellに陥る確率が高く,エラー処理にも一定の限界がある.
プロセスの作成
このため、ES 6はPromise
を導入した.Promise
はECMAScript仕様で定義された標準構築オブジェクトであり、Promise
構造関数は、resolve
およびreject
をパラメータとして受信する非同期処理を実行するコールバック関数をパラメータとして受信する.
resolve
関数呼び出しreject
関数が呼び出される.fulfilled
またはrejected
状態をsettled
状態と呼ぶ.settled
状態はpending
状態ではなく、非同期処理状態である.settled
の状態になると、他の状態に変更することはできません.プロセスは非同期処理状態と同時に非同期処理結果を有する.
すなわち,プロセスは非同期処理状態と処理結果を管理するオブジェクトである.
Premis後続処理方法
プロセスの非同期処理状態が変化する場合、対応する後続処理が必要であり、このプロセスに後続の方法
then, catch, finally
が提供される.プロセスとの非同期処理状態が変化すると、パラメータとして後続の処理方法に渡される
콜백 함수
が選択的に削除され、このときプロセスの처리 결과
がパラメータとして後続の処理方法のコールバック関数に渡される.Promise.prototype.then
次に、メソッドは2つのコールバック関数をパラメータとして渡します.
Promise.prototype.catch
catchメソッドは、コールバック関数を引数として渡します.catchメソッドのコールバック関数は、プロセスが
rejected
の状態にある場合にのみ呼び出されます.Promise.prototype.finally
finallyメソッドは、パラメータとしてコールバック関数を受信します.プロセスが成功しても失敗しても、一度呼び出すだけで、プロセスの状態にかかわらず、共同で実行する必要がある処理があります.
以上の3つの方法は常にpromisを返します.コールバック関数がプロセス以外の値を返す場合は、値を暗黙的に解析または拒否することでプロセスを作成して返します.
エラー処理
const wrongUrl = 'https://jsonplaceholder...';
promiseGet(wrongUrl)
.then(res => console.log(res));
.catch(err => console.error(err));
then
法を用いて第2のコールバック関数を伝達するよりも、catch
法を用いた方が可読性と明確性が高い.したがって,then
メソッドではエラー処理を行わず,catch
メソッドで行うことを提案する.創造する
const url = 'https://...';
promiseGet(`${url}/posts/1`)
.then(({ userId }) => promiseGet(`${url}/users/${userId}`))
.then(userInfo => console.log(userInfo))
.catch(err => console.error(err));
上記の例では、後続の処理方法がthe->then->catchの順序で呼び出され、then, catch, finally
の後続の処理方法は常にプロセスに戻るので、連続的に呼び出すことができる.프로미스 체이닝
と呼ばれています.プロセスは
프로미스 체이닝
によって非同期処理結果を受信し、後続の処理を行うため、非同期処理のコールバックモードでコールバックhellは発生しない.しかし、プロミスは最終的にダイヤルバックモードを使用し、ダイヤルバックモードの可読性が悪い.
=>ES 8導入の
async/await
ソリューションマイクロタスクキュー
setTimeout(() => console.log(1),0);
Promise.resolve()
.then(() => console.log(2))
.then(() => console.log(3));
2->3->1の順で出力します.これは、Promisの後続の処理方法のコールバック関数が태스크 큐
ではなく마이크로태스크 큐
に格納されるためである.마이크로태스크 큐
は、태스크 큐
とは独立したキューであり、Promisの後続処理方法のコールバック関数を一時的に記憶する.마이크로태스크 큐
の優先度は태스크 큐
より高い.すなわち、callスタックが空の場合、イベントループは、마이크로태스크 큐
に待機している関数を最初にインポートして実行し、마이크로태스크 큐
に待機している関数をインポートして実行する.fetch
태스크 큐
オブジェクトと同様に、HTTP要求伝送機能を有するクライアントサイトWeb APIXMLHttpRequest
関数は、HTTPリクエストを送信するURLと、HTTPリクエストメソッド、HTTPリクエストヘッダ、ペイロード等が設定されたオブジェクトを渡す.const promise = fetch(url,[, options])
fetch('https://...);
.then(response => console.log(response));
fetch
関数が返すプロセスはfetch
オブジェクトを404 Not Found
に設定し、HTTPエラー(500 Internal Server Error
やreject
など)が発生した場合、エラーをResponse
に設定せず、ブールタイプのokステータスをfalseに設定します.resolve
プロトコルは、ネットワーク障害(例えばオフライン)またはCORSエラー要求が完了していない場合にのみ実行されます.したがって、
reject
関数を使用する場合、fetch
関数が返すpromisがfetch
であるかどうかを確認して、エラーを明確に処理する必要がある.const wrongUrl = 'https://...';
fetch(wrongUrl)
.then(response => {
if(!response.ok) throw new Error(response.statusText);
return response.json();
})
.then(todo => console.log(todo))
.catch(err => console.error(err));
Reference
この問題について([深い]プロミス), 我々は、より多くの情報をここで見つけました https://velog.io/@shinwonse/딥다이브-프로미스テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol