>웹 프론트엔드 >JS 튜토리얼 >Node.js에서 비동기 기능을 사용하는 방법

Node.js에서 비동기 기능을 사용하는 방법

小云云
小云云원래의
2018-01-18 10:19:401535검색

새 버전의 V8 엔진에서 Node.js는 7.6부터 비동기 기능 기능을 지원합니다. 올해 10월 31일 Node.js 8도 새로운 장기 지원 버전이 되었기 때문에 코드에서 비동기 기능을 안심하고 사용할 수 있습니다. 이 기사에서는 비동기 기능이 무엇인지, 그리고 이 기능이 Node.js 애플리케이션 작성 방식을 어떻게 바꿀 수 있는지 간략하게 소개하겠습니다.

1 비동기 함수란

비동기 함수를 사용하면 동기 코드와 마찬가지로 Promise 기반의 비동기 코드를 작성할 수 있습니다. async 키워드를 사용하여 함수를 정의하면 함수 내에서 wait 키워드를 사용할 수 있습니다. 비동기 함수가 호출되면 Promise가 반환됩니다. 비동기 함수가 값을 반환하면 Promise가 이행되고, 함수에 오류가 발생하면 Promise가 거부됩니다.

await 키워드는 Promise가 해결되기를 기다리고 실현된 값을 반환하는 데 사용할 수 있습니다. Wait에 전달된 값이 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 경로 프로세서가 일시 중지됩니다. .

이 문제를 해결하려면 오류를 처리하는 함수로 비동기 처리기를 래핑해야 합니다.


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 병렬 실행

이러한 프로그램을 작성 중이고 한 작업에 두 개의 입력이 필요하고 하나는 데이터베이스에서 입력이 필요하다고 가정해 보겠습니다. 다른 하나는 외부 서비스에서 가져온 것입니다.


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

이 예에서는 어떻게 되나요?

귀하의 코드가 먼저 사용자에게 전달되고,
그런 다음 제품을 받고,
마지막으로 결제가 이루어집니다.
보시다시피 처음 두 단계 사이에는 상호 의존성이 없으므로 실제로는 병렬로 실행할 수 있습니다. 여기서는 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: 처리되지 않은 약속 거부는 더 이상 사용되지 않습니다. 앞으로는 처리되지 않은 약속 거부로 인해 0이 아닌 종료 코드로 Node.js 프로세스가 종료됩니다.

In 최신 Node.js 버전에서는 Promise가 거부되어 처리되지 않으면 전체 Node.js 프로세스가 중단됩니다. 따라서 필요할 때 try-catch를 사용해야 합니다: ​​


const util = require('util')
비동기 함수 메인() {
노력하다 {
새로운 약속을 기다리십시오((해결, 거부) => {
거부(새 오류('

위 내용은 Node.js에서 비동기 기능을 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.