ホームページ > 記事 > ウェブフロントエンド > Node.js で非同期関数を使用する方法
新しいバージョンの V8 エンジンにより、Node.js は 7.6 以降の非同期関数機能をサポートします。今年 10 月 31 日には、Node.js 8 も新しい長期サポート バージョンになったので、コード内で非同期関数を安心して使用できるようになりました。この記事では、非同期関数とは何か、また非同期関数によって Node.js アプリケーションの作成方法がどのように変わるかを簡単に紹介します。
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 並列実行
このようなプログラムを作成していて、1 つの操作に 2 つの入力 (1 つはデータベースからの 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)
このコードを実行すると、次のようなメッセージが表示されます:
(node:69738) UnhandledPromiseRejectionWarning: 未処理の約束拒否 (拒否 ID : 2) : エラー: error
(node:69738) [DEP0018] DeprecationWarning: 未処理の Promise 拒否は非推奨になります。将来、処理されない Promise 拒否は、ゼロ以外の終了コードで Node.js プロセスを終了します。
In新しい Node.js バージョンでは、Promise が拒否されて処理されない場合、Node.js プロセス全体が中断されます。したがって、必要に応じて try-catch を使用する必要があります:
const util = require('util') 非同期関数 main () { 試す { 新しい Promise((解決、拒否) => { 拒否(新しいエラー('
以上がNode.js で非同期関数を使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。