async、await、promise学習まとめ

4478 ワード

記事の目次
  • 問題
  • 理解
  • Promise
  • async
  • await
  • 解決と総括
  • を参照してください.
    最近はnodejsのサービスをしていますので、結果はzromqで実現されたrpcです.その結果、rpcは引っ掛かりが発生し、メッセージを印刷した後、主にゼロmqメッセージが無くなり、送信後、受信側は受信しなかった.そして、サンプルコードにはasync/awaitという非同期呼出が使われています.よく分かりませんので、資料を探して勉強しました.メモをとってください.
    問題
  • zromqではなぜ非同期方式が使われていますか?
  • async関数の戻り値はどうやって得られますか?これは最初のコードです.
  • function sendMsg(server, msg, uniqueId) {
     if (!this.socket) {
      return null;
     }
    
     var rid;
     if (uniqueId === undefined) {
      rid = uuid.v4() + '_' + this.id;
     } else {
      rid = uniqueId;
     }
    
     this.socket.send([MDP.REQUEST, server, rid, JSON.stringify(msg)])
     return rid;
    }
    
    理解する
    総じて言えば、Promiseとasync/awaitは非同期呼出方式であり、「地域転調」の問題を解決することができます.またasync/awaitの方が同期コードに合うように書いてありますので、読んだ方が分かりやすいです.[1]を参照してください.
    Promise
    Promiseも最初は折り返し問題を解決するために、[2][3]を参照してください.
    Promiseは対象であり、非同期的な操作の最終的な完成または失敗を表しています.
    簡単に言えば、非同期の呼び出しは成功と失敗の結果があります.异なるペースで使い切ってもいいです.各分岐での调整は不要です.つまり、コールバックを送る必要はなくて、最終的に一つのPromiseの対象に処理します.どう処理しますか?時間点はPromise.then関数です.
    const promise1 = new Promise(function(resolve, reject) {
      setTimeout(function() {
        resolve('foo');
      }, 300);
    });
    
    promise1.then(function(value) {
      console.log(value);
      // expected output: "foo"
    });
    
    console.log(promise1);
    // expected output: [object Promise]
    
    また、thenのパラメータは関数ですので、矢印関数[4]が多く見られますので、最初の接触はちょっとおかしいと思います.
    async
    asyncがよく分かります.非同期関数です.参考[5]注意したいのは、その返却値がPomiseオブジェクトですので、最初のsendMsg関数は次のように書きます.同期してsendMsgを呼び出して返した値ridは間違っています.これからも問題があります.
    async function sendMsg(server, msg, uniqueId) {
     //   
     await this.socket.send([MDP.REQUEST, server, rid, JSON.stringify(msg)])
     return rid;
    }
    
    もう一つはasyncでawaitが使えます.async関数を中断します.この時にyieldが捨てたのはPromiseの対象だと理解しています.awaitがすぐに値自体に戻ってもPromiseの対象になります.
    async function test1(){
     var a = await 3;
     return a;
    }
    console.log(test1())
    console.log(test1().then((resolve, reject)=>{
     console.log('resolve:', resolve)
    }))
    //  
    Promise {  }
    Promise {  }
    resolve: 3
    
    await
    awaitは大体以下の点があります.[6]を参照してください.
  • はasync関数でしか
  • を使用できません.
  • await表現は現在のasynctionの実行を停止し、Promise処理が完了するまで待つことができます.
  • 非同期呼出ですので、asyncはこの時awaitに中断されて続けば実行されますが、ここでブロックされません.帰ってきたのはPromiseオブジェクトですが、このPromiseオブジェクトはまだ処理済みではないので、戻ってきたPromise.then関数はまだ実行されていません.参考[5]の例をとる
  • var resolveAfter2Seconds = function() {
      console.log("starting slow promise");
      return new Promise(resolve => {
        setTimeout(function() {
          resolve("slow");
          console.log("slow promise is done");
        }, 2000);
      });
    };
    
    var resolveAfter1Second = function() {
      console.log("starting fast promise");
      return new Promise(resolve => {
        setTimeout(function() {
          resolve("fast");
          console.log("fast promise is done");
        }, 1000);
      });
    };
    
    var concurrentStart = async function() {
      console.log('==CONCURRENT START with await==');
      const slow = resolveAfter2Seconds(); // starts timer immediately
      const fast = resolveAfter1Second(); // starts timer immediately
      // 1. Execution gets here almost instantly
      console.log(await slow); // 2. this runs 2 seconds after 1. 
      console.log(await fast); // 3. this runs 2 seconds after 1., immediately after 2., since fast is already resolved
    }
    
    結果:
    ==CONCURRENT START with await==
    starting slow promise
    starting fast promise
    fast promise is done
    slow promise is done
    slow
    fast
    
    (1)2つの関数resoveAfter 2 SecondsとresoveAfter 1 Secondはawaitを使わずに同じフレームで実行したので、前の3つのプリントはすぐに出てきました.(2)第4条はfast promise is doneを印刷して、第1秒が終わる時にプリントします.resoveAfter 1 Second関数が実行されました.そしてPromise処理は3条が完了しました.主にfastが最後にプリントします.await slowはasyncの最後のコンサートsolie.logの実行をブロックしました.fastのPromiseはすでに処理されました.
    解決と総括
    非同期関数を別の関数に引き出したら、sendMsgの戻り値に影響しません.
    async function send(msg) {
        if (!this.socket) {
            return;
        }
        try {
            await this.socket.send(msg);
        }catch(err){
            console.error('unable to send')
        }
    }
    
    function sendMsg(server, msg, uniqueId) {
     //   
     send.call(this, [MDP.REQUEST, server, rid, JSON.stringify(msg)]).then((resolve, reject)=>{
      console.log('send result...........', resolve, reject)
     });
     return rid;
    }
    
    
    参照
    [1]Nodejs非同期処理の進化[2]Promise[3]Promise使用[4]矢印関数[5]async[6]await[7]NodejsでAync/Await[8][9]を使ってNode.jsのasync/awaitを把握する