ホームページ >ウェブフロントエンド >フロントエンドQ&A >Nodejsでのasyncの使用法は何ですか

Nodejsでのasyncの使用法は何ですか

WBOY
WBOYオリジナル
2022-01-10 11:11:463763ブラウズ

nodejs では、async キーワードを使用して関数を定義できます。async 関数が呼び出されると、Promise が返されます。async 関数が値を返すと、Promise が実現されます。関数が呼び出されたとき、Promise が返されます。 throws エラーが発生すると、Promise は拒否されます。

Nodejsでのasyncの使用法は何ですか

このチュートリアルの動作環境: Windows10 システム、nodejs バージョン 12.19.0、DELL G3 コンピューター。

nodejs での async の使用法とは何ですか

1 async 関数とは何ですか

async 関数を使用すると、 Promise を使用した非同期コードは、同期コードと同じように記述されます。 async キーワードを使用して関数を定義すると、関数内で await キーワードを使用できるようになります。非同期関数が呼び出されると、Promise が返されます。 async 関数が値を返すと、Promise は満たされますが、関数内でエラーがスローされた場合、Promise は拒否されます。

await キーワードは、Promise が解決されるのを待ち、その実現値を返すために使用できます。 await に渡された値が Promise ではない場合、値は解決された Promise に変換されます。

const rp = require('request-promise')
async function main () {
 const result = await rp('https://google.com')
 const twenty = await 20
 // 睡个1秒钟
 await new Promise (resolve => {
  setTimeout(resolve, 1000)
 })
 return result
}
main()
 .then(console.log)
 .catch(console.error)

2 非同期関数への移行

Node.js アプリケーションがすでに Promise を使用している場合は、Promise を待つために元のチェーン呼び出しを書き直すだけで済みます。

アプリケーションがまだコールバック関数を使用している場合は、非同期関数の使用に徐々に切り替える必要があります。いくつかの新機能を開発するときに、この新しいテクノロジーを使用できます。古いコードを呼び出す必要がある場合は、それを Promise にラップして、新しい方法で呼び出すだけです。

これを行うには、組み込みの util.promisify メソッドを使用できます。

const util = require('util')
const {readFile} = require('fs')
const readFileAsync = util.promisify(readFile)
async function main () {
 const result = await readFileAsync('.gitignore')
 return result
}
main()
 .then(console.log)
 .catch(console.error)

3 非同期関数のベスト プラクティス

3.1 Express での非同期関数の使用

express はもともと Promise をサポートしているため、express で非同期関数を使用するのは比較的簡単です:

const express = require('express')
const app = express()
app.get('/', async (request, response) => {
 // 在这里等待 Promise
 // 如果你只是在等待一个单独的 Promise,你其实可以直接将将它作为返回值返回,不需要使用 await 去等待。
 const result = await getContent()
 response.send(result)
})
app.listen(process.env.PORT)

しかし、Keith Smith が指摘したように、上記の例には重大な問題があります - Promise が最終的に拒否された場合。ここではエラー処理が行われないため、Express Route プロセッサは一時停止されます。

この問題を解決するには、エラーを処理する関数で非同期ハンドラーをラップする必要があります。

const awaitHandlerFactory = (middleware) => {
 return async (req, res, next) => {
  try {
   await middleware(req, res, next)
  } catch (err) {
   next(err)
  }
 }
}
// 然后这样使用:
app.get('/', awaitHandlerFactory(async (request, response) => {
 const result = await getContent()
 response.send(result)
}))

3.2 並列実行

たとえば、次のようなプログラムを作成します。操作には 2 つの入力が必要です。1 つはデータベースから、もう 1 つは外部サービスからです。

async function main () {
 const user = await Users.fetch(userId)
 const product = await Products.fetch(productId)
 await makePurchase(user, product)
}

この例では何が起こりますか?

あなたのコードは最初にユーザーを取得し、

次に製品を取得し、

最後に支払いを行います。

ご覧のとおり、最初の 2 つのステップの間には相互依存関係がないため、実際にはこれらを並行して実行できます。ここでは、Promise.all メソッドを使用する必要があります:

async function main () {
 const [user, product] = await Promise.all([
  Users.fetch(userId),
  Products.fetch(productId)
 ])
 await makePurchase(user, product)
}

そして、最も速く解決された Promise の戻り値のみが必要な場合もあります。この場合は、Promise.race メソッドを使用できます。

3.3 エラー処理

次の例を考えてみましょう:

async function main () {
 await new Promise((resolve, reject) => {
  reject(new Error('error'))
 })
}
main()
 .then(console.log)

このコードを実行すると、次のようなメッセージが表示されます:

(ノード: 69738) UnhandledPromiseRejectionWarning: 未処理の Promise 拒否 (拒否 ID: 2): エラー: error

(node:69738) [DEP0018] DeprecationWarning: 未処理の Promise 拒否は非推奨です。将来的には、処理されない Promise 拒否はゼロ以外の終了コードで Node.js プロセスを終了します。

新しい Node.js バージョンでは、Promise が拒否されて処理されない場合、Node.js プロセス全体が中断されます。したがって、必要に応じて try-catch を使用する必要があります。

const util = require('util')
async function main () {
 try {
  await new Promise((resolve, reject) => {
   reject(new Error('

ノード関連の詳細については、nodejs チュートリアル を参照してください。 !

以上がNodejsでのasyncの使用法は何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。