非同期、待機、約束の学習概要


最近nodejsサーバーを取得しているので、結果はzeromqによって実装されたrpcになります。rpcがスタックしていることがわかりました。メッセージを出力した後、zeromqメッセージは主に失われました。送信後、受信側はそれを受信しませんでした。すると、サンプルコードではasync / awaitという非同期コードが使われていることがわかりましたが、理解できないので、覚えてメモを取るための資料を見つけました。

問題

  1. zeromqで非同期モードを使用する理由
  2. 非同期関数の戻り値を取得するにはどうすればよいですか?
    これは最初からのコードです:
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はもともとコールバックの問題を解決するために設計されました。[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パラメータは関数であり、多くの場合、arrow関数[4]が表示されるため、最初は少し奇妙に感じるでしょう。

非同期

非同期は理解しやすく、非同期関数です。参考資料[5]
戻り値はPomiseオブジェクトであるため、最初のsendMsg関数は次の形式で記述されており、sendMsgを同期的に呼び出して取得した戻り値ridは間違っています。最初にも問題が発生しました

async function sendMsg(server, msg, uniqueId) {
 // 省略
 await this.socket.send([MDP.REQUEST, server, rid, JSON.stringify(msg)])
 return rid;
}

もう1つは、非同期でawaitを使用して、非同期機能を中断できることです。この時点で返されたyieldはPromiseオブジェクトであることを理解しています、あなたがすぐに待っている場合でも、戻り値自体もPromiseオブジェクトです

async function test1(){
 var a = await 3;
 return a;
}
console.log(test1())
console.log(test1().then((resolve, reject)=>{
 console.log('resolve:', resolve)
}))
//结果
Promise { <pending> }
Promise { <pending> }
resolve: 3

待つ

Awaitはおそらく以下の点を持っています。[6]を参照してください:

  • 非同期関数でのみ使用できます
  • await式は、現在の非同期関数の実行を中断し、Promise処理の完了を待ちます。
  • これは非同期呼び出しなので、この時点でawaitによってasyncが中断された場合、実行は続行されますが、ここでブロックおよび停止することはありません。返された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)resolveAfter2SecondsとresolveAfter1Secondの2つの関数は待機せずに同じフレームで実行されるため、最初の3枚の印刷はすぐに出力されます
(2)4番目の印刷高速プロミスは最初の1秒の終わりに印刷されます。 resolveAfter1Second関数が実行され、Promiseが処理されます
(3)awaitがasyncの最後のconsole.logの実行をブロックするため、最後の3つの印刷は一緒に印刷されます。速い約束が扱われたとしても

ソリューションと要約

非同期関数を別の関数から引き出します。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] Async / Await in Nodejs
[8]
[9] マスター非同期/ Node.jsで待機

41件のオリジナル記事を公開 賞賛7 20,000回以上の閲覧

おすすめ

転載: blog.csdn.net/pkxpp/article/details/104748170