[TIL] 8/23


非同期処理


동기식 처리はシリアル処理で動作する.一つのことをやり終えて、別のことを順番に行います.この問題は,現在進行中の作業が完了する前に,以降の作業がブロックされることである.
たとえば、サーバと通信して同期してデータを受信し、画面上でレンダリングする場合、サーバにデータを要求して受信する過程で、後続の操作がブロックされるため、レンダリングは行われません.そうすると、ユーザーは空の画面に遭遇します.
これとは異なり、비동기 처리は、タスクが完了していなくても、他のタスクを実行します.サーバにデータを要求して待機するのではなく、他の操作を行うときに、データが来たときに操作を再開します.
上記の例が非同期である場合、データの待機中に画面上の要素をレンダリングして、ユーザーが空白の画面に遭遇しないようにすることができます.

Promise


PromiseはES 6に導入された概念であり,非同期処理のためのオブジェクトである.
従来のコールバックモードの欠点:콜백헬에러 처리의 한계の不足を補い、非同期処理時点を明確に示す利点を有する.

コールバックヘリコプター



非同期処理モデルは、タスクを完了する必要がなく、次のタスクを実行できるため、コードに作成された順序で操作することは保証されません.したがって、処理順序を調整する必要がある場合、たとえば、ある非同期関数の処理結果を使用して別の非同期関数を呼び出す必要がある場合は、コールバック関数のネストを続行する必要があります.このときコールバックが発生し,可読性も悪く複雑度が増し,エラー処理が困難になる.

Promiseの作成


Promiseオブジェクトはコンストラクション関数によって生成されます.他のオブジェクトと同様に、コンストラクション関数にnewを追加して作成できます.Promiseオブジェクトには4つのステータス情報があります.
  • pending:非同期処理はまだ実行されていません
  • 完了済み
  • :非同期処理成功
  • 拒否
  • :非同期処理失敗
  • ソリューション:非同期処理成功/失敗
  • Promiseコンストラクション関数は,非同期処理結果に基づいて実行されるコールバック関数をパラメータとして渡す.内部で非同期処理タスクを実行し、非同期処理に成功した場合、パラメータに渡された解析関数が呼び出されると、関数は完了状態になります.失敗した場合、拒否関数が呼び出されると、関数は拒否状態になります.
    // Promise 객체 생성
      new Promise((resolve, reject) => {
        /*
        * ... 비동기 처리 구현 ...
        */
        if (/* 성공 */) {
          // resolve 메소드를 호출하면서 처리 결과를 전달
          resolve(/* 처리 결과 */); // 이 처리 결과는 Promise 객체의 후속 처리 메소드로 전달됨
        } else {
          // reject 메소드를 호출하면서 에러 메시지를 전달
          reject(new Error(/* status */)); // 이 에러 메세지는 후속 처리 메소드로 전달됨
        }
      });

    後続の処理方法


    Promiseの非同期関数はPromiseオブジェクトを返します.この非同期関数を呼び出した呼び出し元は、Promiseオブジェクトの後続の処理方法によって処理結果またはエラーメッセージを受信して処理します.
  • then:パラメータとして2つのコールバック関数が渡されます.1つはPromiseオブジェクトが成功したときに呼び出され、もう1つは失敗したときに呼び出されます.そしてPromiseに戻ります.
  • catch:非同期処理後、メソッドにエラーが発生した場合に呼び出されます.Promiseに戻ります.
  • 非同期処理では、エラーが発生した場合、メソッドの2番目のコールバック関数またはcatchを使用して処理します.catchメソッドは、内部呼び出しで定義されていないthenに最初のパラメータを渡します.
    //then 단독 사용
    promiseFunction(/* 주소 */)
      .then(res => console.log(res), err => console.error(err));
    // 이 경우 두 번째 콜백 함수는 첫 번째 콜백 함수에서 발생한 에러를 캐치하지 못함 ㅠㅠ
    
    // then과 then 사용
    promiseFunction(/* 주소 */)
      .then(res => console.log(res))
      .then(undefined, err => console.error(err)); 
    
    // then과 catch 사용
    promiseFunction(/* 주소 */)
      .then(res => console.log(res))
      .catch(err => console.error(err)); 
    3つの方法がありますが.
  • メソッドで2つのコールバック関数を使用すると、2番目のコールバック関数は最初のコールバック関数で発生したエラーをキャプチャできません.
  • コードは複雑になり、可読性が悪い
  • はcatchを呼び出し、非同期処理中に発生したエラーだけでなく、その後発生したエラーもキャプチャできます.
  • catchメソッドを使用して、可読性が良く、意味伝達が明確で、
  • したがって、メソッドですべて処理するのではなく、「次」を呼び出してcatchを呼び出すことをお勧めします.

    정적 메소드


    Promiseオブジェクトには4つの静的メソッドがあります.

    Promise.resolve, Promise.reject


    Promise.決意と約束.requestはパラメータに渡された値をPromiseでラップします.でもPromiseresolveメソッドは、値を解析するためのPromiseを作成します.executeは拒否値のPromiseを生成します.
    // resolve1과 resolve2는 동일하게 동작함
    const resolve1 = Promise.resolve(/* 값 */);
    const resolve2 = new Promise(resolve => resolve(/* 값 */));
    resolve1.then(console.log); // 값
    
    // reject1과 reject2는 동일하게 동작함
    const reject1 = Promise.reject(new Error('에러'));
    const reject2 = new Promise((resolve, reject) => reject(new Error('에러')));
    reject1.catch(console.log) // Error: 에러

    Promise.all, Promise.race


    Promise.allとPromise.raceはPromiseを含むかわいい子をパラメータとして受け入れます.
    Promise.allは、入力されたすべてのプログラマブル論理情報を並列に処理する.新しいプロトコルを返し、すべてのプロトコルの処理が終了するまで待機し、処理結果を解析または拒否します.すべての約束が成功した場合、新しい約束が返され、各約束が解決した結果が配列に配置されます.この場合、パラレルプロセッサであるため、Promise処理が完了する順序が最初に入力した順序と異なる場合があるが、結果を返すPromiseはPromise入力の順序で結果を配列に入れることで、処理順序が保証される.逆に、処理中に失敗があった場合は、最初の失敗したPromiseが拒否したエラーを拒否した新しいPromiseをすぐに返します.
    パラメータとして渡されるかわいい要素がPromiseでなければPromiseです決意ですべての要素をかばう.
    Promise.all([
      new Promise(/* 함수 */), 
      new Promise(/* 함수 */), 
      new Promise(/* 함수 */) 
    ]).then(console.log) // 배열
      .catch(console.log);
    Promise.raceは、すべてのPromiseを並列に処理するのではなく、最初に処理されたPromiseが解析した処理結果を解析する新しいpromiseを返します.エラーはPromiseallと同様に、最初に失敗したPromiseは、拒否されたエラーの新しいPromiseをすぐに返します.
    Promise.race([
      new Promise(/* 함수 */), 
      new Promise(/* 함수 */), 
      new Promise(/* 함수 */) 
    ]).then(console.log) // 가장 먼저 처리된 결과
      .catch(console.log);

    ソース

  • Promise