Node.js의 비동기성에 대한 심층 분석
이 글에서는 Node.js의 비동기식에 대해 자세히 소개합니다. 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.
Node.js 비동기에 대해 피할 수 없는 두 가지가 있습니다: 비 차단 I/O 및 이벤트 루프입니다. Node.js가 고성능이라 할 수 있고 온라인 환경에서 사용할 수 있는 것은 바로 이 두 가지 때문입니다. 그럼 Node.js의 비동기 메커니즘과 사용법에 대해 알아볼까요? [추천 학습: "nodejs 튜토리얼"]
Node.js의 비차단 I/O
- I/O는
입력
/출력
입니다. 시스템의Input
/Output
,一个系统的输入和输出。 - 阻塞 I/O 和非阻塞 I/O 的区别就在于系统接收输入再到输出期间,能不能接收其他输入。
以点菜吃饭为例子:去饭堂点菜吃饭需要排队等待,在这个过程中,阿姨每次只能接待一个人,“点菜-阿姨抖勺装菜-把饭菜给到你”这个过程中阿姨并不能接收其他人的点菜,这个就是阻塞 I/O;而去餐馆点菜吃饭,去到餐馆就可以跟服务员你要吃番茄炒蛋,服务员记下来之后交给后厨,这时候来了另一桌人就把服务员招呼过去说想吃小龙虾,也就是说,在把菜给你上上来之前服务员接收了其他人的点菜,那这个就是非阻塞型 I/O。
理解非阻塞 I/O 的要点在于
-
确定一个进行
Input
/Output
的系统。 - 思考在 I/O 过程中,能不能进行其他 I/O。
那在点菜吃饭这个例子中,一个进行 Input
/Output
的系统就是点餐-后厨(阿姨)处理-上菜这样一个能让你吃上饭的系统;点餐就是 Input
,上菜就是 Output
,在这个例子中判断两者是非阻塞型还是阻塞型的关键就在于在点菜上菜这个过程中能不能接受其它的点菜上菜。就好比你点了个佛跳墙,等上菜可能就要好久了,然后来的人都是点一些简单的菜品,一分钟炒一份炒粉的那种,可能就是来来回回几波人之后都还没能给你上菜。
而 Node.js 它是用来操纵计算机的,一些如读取文件之类的操作是非常耗时的,要是不能进行其它的 I/O,那么处理效率就很会很低了,这也是 Node.js 是非阻塞型 I/O 的一个原因。
Node.js 的事件循环
Node.js 启动的时候会初始化由 libuv 提供的事件循环,每次的事件循环都包含6个阶段,这6个阶段会在每一次的事件循环当中按照下图当中的顺序反复执行,如下图:
-
timers
阶段:这个阶段执行timer
(setTimeout
、setInterval
)的回调 - I/O
callbacks
阶段 :处理一些上一轮循环中的少数未执行的 I/O 回调 -
idle
,prepare
阶段 :仅 Node 内部使用 -
poll
阶段 :获取新的 I/O 事件, 适当的条件下 Node 将阻塞在这里 -
check
阶段 :执行setImmediate()
的回调 -
close callbacks
阶段:执行socket
的close
事件回调
每个阶段都有一个先入先出的(FIFO)的用于执行回调的队列,事件循环运行到每个阶段,都会从对应的回调队列中取出回调函数去执行,直到队列当中的内容耗尽,或者执行的回调数量达到了最大。
然后事件循环就会进入下一个阶段,然后又从下一个阶段对应的队列中取出回调函数执行,这样反复直到事件循环的最后一个阶段。而事件循环也会一个一个按照循环执行,直到进程结束。
事件循环当中的6个宏队列和微队列的关系如下:微队列(microtask
)在事件循环的各个阶段之间执行,或者说在事件循环的各个阶段对应的宏队列(macrotask
입력 및 출력
Blocking I/O와 Non-Blocking I/O의 차이점은 입력에서 출력까지의 기간 동안 시스템이 다른 입력을 받을 수 있는지 여부에 있습니다. 음식 주문을 예로 들어보겠습니다. 매점에서 음식을 주문하려면 줄을 서서 기다려야 합니다. 이 과정에서 이모는 한 번에 한 사람만 받을 수 있습니다. "음식 주문 - 이모" 숟가락을 흔들어 음식을 담는다 - "음식을 가져오는" 과정에서 이모님은 다른 사람의 주문을 받아들일 수 없습니다. 이는 음식을 주문하기 위해 식당에 갈 때 알 수 있습니다. 레스토랑에 가면 토마토 스크램블 에그를 먹고 싶다고 웨이터가 적어서 셰프에게 건네는데, 이때 다른 테이블 사람이 와서 웨이터를 불러 가재를 먹고 싶다고 말한다. 즉, 웨이터
입력
/출력
을 수행하는 시스템을 결정🎜하는 것입니다. 🎜🎜I/O 프로세스 중에 다른 I/O를 수행할 수 있는지 생각해 보세요🎜. 🎜음식 주문의 예에서 입력
/출력
을 수행하는 시스템은 주문 - 주방(이모)이 처리 - 서빙은 먹을 수 있는 시스템입니다. 주문은 입력
이고 서빙은 출력
입니다. 이 예에서 핵심은 두 가지가 무엇인지 결정하는 것입니다. 주문 및 서빙 과정에서 다른 주문 및 요리를 수락할 수 있는지 여부. 마치 부다 점프 오버 더 월(Buddha Jumps Over the Wall)을 주문하면 음식이 나오기까지 오랜 시간이 걸릴 수 있고, 그러면 오는 사람들은 튀길 수 있는 간단한 볶음면을 주문할 것입니다. 1분 정도 사람들이 오고 가는 바람에 아직 음식을 대접할 수 없었을 것 같아요. 🎜🎜그리고 Node.js는 컴퓨터를 제어하는 데 사용됩니다. 파일 읽기와 같은 일부 작업은 시간이 많이 걸립니다. 다른 I/O를 수행할 수 없으면 처리 효율성도 매우 낮습니다. 논블로킹 I/O의 이유. 🎜🎜Node.js 이벤트 루프🎜🎜🎜Node.js는 시작 시 libuv에서 제공하는 🎜이벤트 루프🎜를 초기화합니다. 각 이벤트 루프에는 6단계가 포함됩니다. 아래 표시된 순서대로 각 이벤트 루프에서 반복적으로 실행됩니다. 🎜🎜
🎜🎜🎜timers
단계: 이 단계는 timer
( setTimeout
, setInterval) 콜백🎜I/O <code>콜백
단계: 이전 주기에서 실행되지 않은 몇 가지 I/O를 처리합니다. 콜백🎜idle
, prepare 단계: Node에서 내부적으로만 사용됩니다.🎜poll
단계: 새로운 I/O 이벤트를 가져옵니다. Node는 적절한 조건에서 여기를 차단합니다.🎜check
단계: setImmediate()
의 콜백 실행🎜콜백 닫기
단계: close
이벤트 콜백 실행 of socket
🎜🎜각 단계에는 FIFO(선입선출) 기능이 있습니다. 콜백 실행을 위한 큐와 관련하여 이벤트 루프의 각 단계에서 콜백 함수는 해당 콜백 큐에서 꺼내어 큐의 내용이 소진되거나 실행된 콜백 수가 최대🎜에 도달할 때까지 실행됩니다. 🎜🎜이후 이벤트 루프는 다음 단계로 진입하고, 다음 단계에 해당하는 큐에서 콜백 함수를 꺼내어 실행하며, 이는 이벤트 루프의 마지막 단계까지 반복됩니다. 이벤트 루프도 프로세스가 끝날 때까지 하나씩 실행됩니다. 🎜🎜이벤트 루프의 6개 매크로 큐와 마이크로 큐의 관계는 다음과 같습니다. 마이크로 큐(microtask
)는 이벤트 루프의 다양한 단계 사이에서 실행되거나 이벤트 루프의 각 단계에서 해당 매크로가 실행됩니다. 큐 사이에서 실행되는 이벤트 루프(macrotask
). 🎜🎜🎜🎜🎜여기 특히 혼란스러운 버전 변경이 있습니다: 🎜
- Node10 및 이전 버전인 경우: 매크로 대기열에 여러 개의 매크로 작업이 있으며 매크로 대기열의 모든 매크로 작업이 완료될 때까지 마이크로 대기열의 마이크로 작업이 실행되지 않습니다
- Node11 및 이전 버전인 경우 이후 버전: 단계의 매크로 작업(
setTimeout
, setInterval
및 setImmediate
)이 실행되면 I/O를 제외한 세 가지 중 하나 ), 즉시 마이크로태스크 대기열을 실행하고, 마이크로큐에 있는 모든 마이크로태스크를 실행한 후, 바로 지금 매크로큐로 돌아와서 다음 매크로태스크를 실행합니다. 이는 setTimeout
,setInterval
和 setImmediate
三者其中之一,不包括I/O)就立刻执行微任务队列,执行完微队列当中的所有微任务再回到刚才的宏队列执行下一个宏任务。这就跟浏览器端运行一致了。
Node.js 异步编程 - callback
- 回调函数格式规范
error-first callback
node-style callback
- 第一个参数是
error
,后面的参数才是结果。
// 第一个参数是错误捕获
interview(function (err, res) {
if (err) {
console.log('cry')
return;
}
console.log('smile')
})
function interview(callback) {
setTimeout(() => {
if (Math.random() > 0.2) {
callback(null, 'success')
} else {
callback(new Error('fail'))
}
}, 500)
}
로그인 후 복사
setTimeout
, setInterval
및 setImmediate
)이 실행되면 I/O를 제외한 세 가지 중 하나 ), 즉시 마이크로태스크 대기열을 실행하고, 마이크로큐에 있는 모든 마이크로태스크를 실행한 후, 바로 지금 매크로큐로 돌아와서 다음 매크로태스크를 실행합니다. 이는 setTimeout
,setInterval
和 setImmediate
三者其中之一,不包括I/O)就立刻执行微任务队列,执行完微队列当中的所有微任务再回到刚才的宏队列执行下一个宏任务。这就跟浏览器端运行一致了。callback
error-first callback
node-style callback
error
,后面的参数才是结果。// 第一个参数是错误捕获 interview(function (err, res) { if (err) { console.log('cry') return; } console.log('smile') }) function interview(callback) { setTimeout(() => { if (Math.random() > 0.2) { callback(null, 'success') } else { callback(new Error('fail')) } }, 500) }
异步流程控制:回调地狱、异步并发等问题
npm
:async.js
;可以通过async.js
来控制异步流程thunk
:一种编程方式
Node.js 异步编程 – Promise
- 可以通过字面意思理解,
Promise
是承诺的意思;当前事件循环得不到的结果,但未来的事件循环会给到你结果 - 它是一个状态机,状态一旦确定为
resolved
或rejected
就不会改变pending
:初始状态,还没得到结果的状态fulfilled
/resolved
:成功状态rejected
:失败状态
链式调用:.then
和 .catch
resolved
状态的Promise
会回调后面的第一个.then
rejected
状态的Promise
会回调后面的第一个.catch
- 任何一个
rejected
状态且后面没有.catch
的Promise
,都会造成浏览器/ Node 环境的全局错误
// promise的状态转换以及通过then获取内容 const promise = new Promise((resolve, reject) => { setTimeout(function () { resolve(3); // reject(new Error(4)) }, 500) }) promise.then(function (result) { console.log(result) }).catch(function (err) { console.log(err) }) setTimeout(() => { console.log(promise) }, 800)
执行 then
和 catch
会返回一个新 Promise
,该 Promise
最终状态根据 then
和 catch
的回调函数的执行结果决定
- 如果回调函数最终是
throw
,该Promise
是rejected
状态 - 如果回调函数最终是
return
,该Promise
是resolved
状态 - 但如果回调函数最终
return
了一个Promise
,该Promise
会和回调函数return
的Promise
状态保持一致
Node.js 异步编程 – async
/await
async function
是Promise
的语法糖封装- 异步编程的终极方案 – 以同步的方式写异步
await
关键字可以“暂停”async function
的执行await
关键字可以以同步的写法获取Promise
的执行结果try-catch
可以获取await
所得到的错误
(async function () { await findJob() console.log('trip') })() async function findJob() { try { // 进行三轮面试 await interview(1); await interview(2); await interview(3); console.log('smile') } catch (e) { console.log('cry at ' + e.round) } } // 进行第round轮面试 function interview(round) { return new Promise((resolve, reject) => { setTimeout(() => { if (Math.random() < 0.2) { const error = new Error('failed'); error.round = round; reject(error); } else { resolve('success'); } }, 500) }) }
这是一个穿越事件循环存在的 function
。
总结
- 理解非阻塞 I/O 主要在于确定一个进行 I/O 的系统,然后思考判断能不能进行其它 I/O。
- Node.js 的事件循环在 Node11 版本及之后是和浏览器的事件循环运行一致的,要注意区分。
- Node.js 异步编程的规范是第一个参数是
error
,后面的才是结果。 -
Promise
是一个状态机,初始状态为pending
,一旦确定状态为resolved
或rejected
就不会改变,可以通过.then
和.catch
进行链式调用。 -
async
/await
브라우저 측 작업과 일치 합니다.
콜백
🎜오류 우선 콜백🎜🎜<code>노드 스타일 콜백
🎜🎜🎜🎜첫 번째 매개변수는 error
이고, 다음 매개변수는 결과입니다. 🎜🎜rrreee🎜비동기 프로세스 제어: 콜백 지옥, 비동기 동시성 및 기타 문제🎜🎜🎜npm
: async.js
를 전달할 수 있음 async.js code> 비동기 프로세스를 제어하려면🎜🎜<code>thunk
: 프로그래밍 방법🎜🎜🎜Node.js 비동기 프로그래밍 – Promise
🎜 🎜🎜 문자 그대로 이해할 수 있습니다. Promise
는 약속을 의미합니다. 현재 이벤트 루프는 결과를 얻을 수 없지만 미래의 이벤트 루프는 결과를 제공합니다🎜🎜이것은 상태 머신입니다. 상태가 해결됨
또는 거부
로 결정되면 변경되지 않습니다🎜🎜보류
: 초기 상태, 결과가 나오지 않은 상태 아직 획득함🎜🎜fulfilled
/ resolved
: 성공 상태 🎜🎜거부됨
: 실패 상태 🎜🎜🎜🎜🎜체인 호출: .then
및 .catch
🎜🎜🎜resolved
상태 Promise
는 첫 번째 .then
🎜를 콜백합니다. 🎜rejected
상태의 Promise
는 첫 번째 .catch
🎜🎜않은 모든 rejected
상태를 콜백합니다. .catch
의 Promise
를 따르면 브라우저/노드 환경에서 전역 오류가 발생합니다🎜🎜rrreee🎜then
및 catch를 실행하면
는 then
및 catch
의 콜백 함수 실행 결과에 따라 최종 상태가 결정되는 새로운 Promise
를 반환합니다. 🎜🎜 🎜콜백 함수가 throw
로 끝나는 경우 Promise
는 rejected
상태가 됩니다. 🎜🎜콜백 함수가 로 끝나는 경우 return
, Promise
는 해결
상태입니다 🎜🎜그러나 콜백 함수가 최종적으로 Promise
를 반환
하면 code>에서 Promise
는 콜백 함수 return
🎜🎜🎜Node.js 비동기 프로그래밍 – async
/await
🎜🎜🎜async function
은 의 구문 설탕 패키지입니다. >비동기 프로그래밍에 대한 약속
🎜🎜궁극적인 솔루션 - 동기 방식으로 비동기 작성🎜🎜await
키워드는 비동기 함수
🎜🎜의 실행을 "일시 중지"할 수 있습니다. await
키워드를 사용할 수 있음 동기식 쓰기 방식으로 Promise
🎜🎜try-catch
의 실행 결과를 얻어 await에서 얻은 오류를 얻을 수 있음
🎜🎜🎜🎜rrreee🎜이벤트 루프를 통해 존재하는 함수
입니다. 🎜🎜요약🎜
🎜🎜비차단 I/O를 이해하는 것은 주로 🎜I/O를 수행하는 시스템을 결정한 다음 다른 I/O가 O 공연 가능 🎜. 🎜🎜Node.js의 🎜이벤트 루프🎜는 Node11 버전 이상에서 브라우저의 이벤트 루프와 동일하게 실행되므로 차이점에 주의하시기 바랍니다. 🎜🎜Node.js 비동기 프로그래밍의 사양은 첫 번째 매개변수가error
이고 그 결과는 다음과 같습니다. 🎜🎜Promise
는 🎜상태 머신🎜입니다. 초기 상태는 pending
입니다. 상태가 결정되면 해결됨
또는 가 됩니다. 거부됨
변경되지 않으며 .then
및 .catch
를 통해 연쇄 호출이 가능합니다. 🎜🎜async
/await
🎜동기식으로 비동기 작성🎜은 비동기 프로그래밍에 대한 궁극적인 솔루션입니다. 🎜🎜🎜더 많은 프로그래밍 관련 지식을 보려면 🎜프로그래밍 비디오🎜를 방문하세요! ! 🎜위 내용은 Node.js의 비동기성에 대한 심층 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Non-Blocking, Event-Driven 기반으로 구축된 Node 서비스는 메모리 소모가 적다는 장점이 있으며, 대규모 네트워크 요청을 처리하는데 매우 적합합니다. 대규모 요청을 전제로 '메모리 제어'와 관련된 문제를 고려해야 합니다. 1. V8의 가비지 수집 메커니즘과 메모리 제한 Js는 가비지 수집 기계에 의해 제어됩니다.

빠른 적용: PHP의 실제 개발 사례 분석 여러 파일의 비동기 HTTP 다운로드 인터넷의 발전으로 파일 다운로드 기능은 많은 웹 사이트와 응용 프로그램의 기본 요구 사항 중 하나가 되었습니다. 여러 파일을 동시에 다운로드해야 하는 시나리오의 경우 기존 동기 다운로드 방법은 비효율적이고 시간이 많이 걸리는 경우가 많습니다. 이러한 이유로 PHP를 사용하여 HTTP를 통해 여러 파일을 비동기적으로 다운로드하는 것이 점점 더 일반적인 솔루션이 되었습니다. 본 글에서는 실제 개발 사례를 통해 PHP 비동기 HTTP를 활용하는 방법을 자세히 분석해 보겠습니다.

초기에 JS는 브라우저 측에서만 실행되었습니다. 유니코드로 인코딩된 문자열은 처리하기 쉬웠지만 바이너리 및 유니코드가 아닌 인코딩된 문자열을 처리하는 것은 어려웠습니다. 그리고 바이너리는 컴퓨터의 가장 낮은 데이터 형식인 비디오/오디오/프로그램/네트워크 패키지입니다.

인터넷의 지속적인 발전과 대중화로 인해 이메일은 사람들의 생활과 업무에 없어서는 안 될 부분이 되었으며, SMTP(Simple Mail Transfer Protocol)는 이메일 전송을 위한 중요한 프로토콜 중 하나입니다. PHP용 비동기 네트워크 통신 프레임워크인 Swoole은 비동기 SMTP 작업을 지원하여 이메일 전송을 더욱 효율적이고 안정적으로 만들어줍니다. 이 기사에서는 Swoole이 동기화 사용을 포함하여 비동기 SMTP 작업을 지원하는 방법을 소개합니다.

인터넷 비즈니스 규모가 지속적으로 성장함에 따라 높은 동시성, 고성능에 대한 요구가 점점 높아지고 있으며, PHP용 네트워크 통신 프레임워크인 Swoole은 개발자들의 선호도가 높아지고 있습니다. 그중 Swoole은 가장 일반적인 애플리케이션 시나리오 중 하나인 비동기 AMQP를 지원합니다. 이제 Swoole이 비동기 AMQP 작업을 어떻게 지원하는지 살펴보겠습니다. 먼저 AMQP가 무엇인지 명확히 해야 합니다. AMQP(AdvancedMessageQueuingProtocol) 고급

동시 및 비동기 프로그래밍 동시 프로그래밍은 동시에 실행되는 여러 작업을 처리하며, 비동기 프로그래밍은 작업이 스레드를 차단하지 않는 일종의 동시 프로그래밍입니다. asyncio는 프로그램이 메인 스레드를 차단하지 않고 I/O 작업을 수행할 수 있도록 하는 Python의 비동기 프로그래밍용 라이브러리입니다. 이벤트 루프 asyncio의 핵심은 I/O 이벤트를 모니터링하고 해당 작업을 예약하는 이벤트 루프입니다. 코루틴이 준비되면 이벤트 루프는 I/O 작업을 기다릴 때까지 이를 실행합니다. 그런 다음 코루틴을 일시 중지하고 다른 코루틴을 계속 실행합니다. 코루틴 코루틴은 실행을 일시 중지하고 다시 시작할 수 있는 함수입니다. asyncdef 키워드는 코루틴을 만드는 데 사용됩니다. 코루틴은 I/O 작업이 완료될 때까지 기다리기 위해 wait 키워드를 사용합니다. 다음과 같은 asyncio의 기본 사항

Vue.js는 애플리케이션에서 사용자 인터페이스를 구축하는 방법을 제공하는 인기 있는 프런트 엔드 JavaScript 프레임워크입니다. Vue.js 문서에서 특히 비동기 요청 기능을 사용하는 방법에 대한 많은 유용한 정보를 찾을 수 있습니다. 비동기 요청 기능은 애플리케이션에서 비동기 작업을 수행하는 방법입니다. 서버에서 데이터를 가져오고, 입력을 처리하고, 양식을 검증하는 데 사용됩니다. 일반적으로 비동기 요청 기능은 Promise, async 및 Wait와 같은 Java 기능과 결합되어야 합니다.

비동기식 및 비차단 기술을 사용하여 전통적인 예외 처리를 보완하여 보다 응답성이 뛰어나고 효율적인 Java 애플리케이션을 생성할 수 있습니다. 비동기식 예외 처리: 다른 스레드나 프로세스에서 예외를 처리하여 기본 스레드가 계속 실행되도록 하고 차단을 방지합니다. 비차단 예외 처리: I/O 작업이 잘못되었을 때 이벤트 기반 예외 처리를 포함하여 스레드 차단을 방지하고 이벤트 루프가 예외를 처리하도록 허용합니다.
