web-dev-qa-db-ja.com

async / awaitはイベントループをブロックしますか?

Node.jsガイドから イベントループをブロックしないでください を読んでいました。言っている行がありました:

イベントループを決してブロックしないようにしてください。つまり、JavaScriptコールバックのそれぞれがすばやく完了する必要があります。もちろん、これはawaitPromise.thenなどにも当てはまります。

awaitingが解決するのに時間がかかっているデータベースへの一部のAPI呼び出しが解決に時間がかかっているとしたら、それはそのawait呼び出しでイベントループをブロックしたことを意味しますか? ?

その後、私はいくつかの自己記述コードのテストを開始しましたが、テスト後もawaitによるブロックがどのように機能するかはまだわかりません。ここにいくつかのテストコードがあります:

仮定として、私はテストにエクスプレスを使用しています。この場合、/testルートに対して2つのAPI呼び出しを行うとイベントループがブロックされる理由を理解しています。

function someHeavyWork() {
  // like calling pbkdf2 function
}

app.get('/test', (req, res) => {
  someHeavyWork();
  res.json(data);
});

しかし、この場合はそれは起こりません。

function fakeDBCall() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(data);
    }, 5000)
  })
}

app.get('/test', async (req, res) => {
  const data = await fakeDbCall();
  res.json(data);
})

これは、async/awaitの場合にブロックがどのように機能するかを理解していないためかもしれません。

13
Aziz

見かけとは逆に、awaitはブロックしません。それは約束よりも構文糖です。ブロックされるものはありません。コードが同期できるようにブロックしているように見えるかもしれませんが、それは約束を守るだけです。たとえば、これは同期的に見える場合があります。

const response = await fetch(…);
const json = await response.json();
const foo = JSON.parse(json); // Using json here, even though my request was async!

しかし、そうではありません。あなたがそれを砂糖を取り除いたら、あなたが得るすべてはノンブロッキングである約束です:

fetch(…)
  .then(response => response.json())
  .then(json => {
    const foo = JSON.parse(json);
  });

awaitがブロックされていたら、それは絶対に破滅的でしょう。 JavaScriptランタイムは一般にシングルスレッドです。つまり、ユーザーの要求やその他のプロセスは、ファイルシステムを使用するなど、リクエストやその他の非同期操作を行うたびに停止します。関連するメモとして、これは動的インポートとともに トップレベルに対する主要な引数await です。

26
Li357

awaitはnotイベントループをブロックします。実際、JavaScriptがawaitを検出すると、すぐに制御をイベントループに戻します。

2
Evert

Async関数はpromiseを返し、リクエストとレスポンスを渡しています。res.json(data)を変更してres.json(data)を返します。

非同期関数が値を返すとき、promiseは解決されます。関数にエラーが含まれている場合、res.json(data)を返す清潔さのために、promiseは拒否され、関数が解決されます。

0