Angular의 zone.js에 대한 심층 분석 및 작동 방식
이 기사에서는 Angular의 zone.js를 살펴보고, 예제를 통해 zone.js의 기능을 보여주고, 그 뒤에 있는 작동 원리를 간략하게 분석합니다. 모든 사람에게 도움이 되기를 바랍니다.
아마도 Angular가 zone.js
를 사용한다는 말을 들어보셨을 것입니다. 그런데 Angular는 왜 zone.js
를 사용하고 어떤 기능을 제공할 수 있나요? 오늘 우리는 zone.js
에 대해 이야기하기 위해 별도의 기사를 작성할 것입니다. Angular 프레임워크에서의 역할은 다음 기사에서 논의될 것입니다. [관련 튜토리얼 추천: "zone.js
, 但 Angular 为什么要使用zone.js
, 它能够提供哪些功能呢?今天我们单独写一篇文章聊聊zone.js
,关于它在 Angular 框架中发挥的作用将在下一篇文章讲述。【相关教程推荐:《angular教程》】
什么是 Zone ? 官方文档是这么解释的:Zone 是一个跨多个异步任务的执行上下文。一句话总结来说,Zone 在拦截或追踪异步任务方面有着特别强大的能力。下面我们将通过一个示例来展示它的能力,并简单剖析一下背后的工作原理。
<button id="b1">Bind Error</button> <button id="b2">Cause Error</button> <script> function main() { b1.addEventListener('click', bindSecondButton); } function bindSecondButton() { b2.addEventListener('click', throwError); } function throwError() { throw new Error('aw shucks'); } main(); </script>
这是一个简单的 HTML 页面。页面加载时会给第一个按钮添加点击事件,其点击事件函数的功能是给第二个按钮添加点击事件,而第二个按钮的点击事件函数功能是抛出一个异常。我们依次点击第一个按钮和第二个按钮,控制台显示如下:
(索引):26 Uncaught Error: aw shucks at HTMLButtonElement.throwError ((索引):26:13)
但是如果我们通过zone.js
启动运行代码,控制台输出会有什么不同呢,我们先调整启动代码:
Zone.current.fork( { name: 'error', onHandleError: function (parentZoneDelegate, currentZone, targetZone, error) { console.log(error.stack); } } ).fork(Zone.longStackTraceZoneSpec).run(main);
此时控制台输出如下:
Error: aw shucks at HTMLButtonElement.throwError ((索引):26:13) at ZoneDelegate.invokeTask (zone.js:406:31) at Zone.runTask (zone.js:178:47) at ZoneTask.invokeTask [as invoke] (zone.js:487:34) at invokeTask (zone.js:1600:14) at HTMLButtonElement.globalZoneAwareCallback (zone.js:1626:17) at ____________________Elapsed_571_ms__At__Mon_Jan_31_2022_20_09_09_GMT_0800_________ (localhost) at Object.onScheduleTask (long-stack-trace-zone.js:105:22) at ZoneDelegate.scheduleTask (zone.js:386:51) at Zone.scheduleTask (zone.js:221:43) at Zone.scheduleEventTask (zone.js:247:25) at HTMLButtonElement.addEventListener (zone.js:1907:35) at HTMLButtonElement.bindSecondButton ((索引):23:10) at ZoneDelegate.invokeTask (zone.js:406:31) at Zone.runTask (zone.js:178:47) at ____________________Elapsed_2508_ms__At__Mon_Jan_31_2022_20_09_06_GMT_0800_________ (localhost) at Object.onScheduleTask (long-stack-trace-zone.js:105:22) at ZoneDelegate.scheduleTask (zone.js:386:51) at Zone.scheduleTask (zone.js:221:43) at Zone.scheduleEventTask (zone.js:247:25) at HTMLButtonElement.addEventListener (zone.js:1907:35) at main ((索引):20:10) at ZoneDelegate.invoke (zone.js:372:26) at Zone.run (zone.js:134:43)
通过对比我们知道:不引入zone.js
时,我们通过错误调用栈仅仅能够知道,异常是由按钮2的点击函数抛出。而引入了zone.js
后,我们不仅知道异常是由按钮2的点击函数抛出,还知道它的点击函数是由按钮1的点击函数绑定的,甚至能够知道最开始的应用启动是main
函数触发。这种能够持续追踪多个异步任务的能力在大型复杂项目中异常重要,现在我们来看zone.js
是如何做到的吧。
zone.js
接管了浏览器提供的异步 API,比如点击事件、计时器等等。也正是因为这样,它才能够对异步操作有更强的控制介入能力,提供更多的能力。现在我们拿点击事件举例,看看它是如何做到的吧。
proto[ADD_EVENT_LISTENER] = makeAddListener(nativeAddEventListener,..)
上述代码中,proto
便指的是EventTarget.prototype
,也就是说这行代码重新定义了addEventListener
函数。我们继续看看makeAddListener
函数做了什么。
function makeAddListener() { ...... // 关键代码1 nativeListener.apply(this, arguments); ...... // 关键代码2 const task = zone.scheduleEventTask(source, ...) ...... }
该函数主要做了两件事,一是在自定义函数中执行浏览器本身提供的addEventListener
函数,另外一个就是为每个点击函数安排了一个事件任务,这也是zone.js
对异步 API 有强大介入能力的重要因素。
现在我们再回到本文开头的示例中,看看控制台为什么能够输出完整的完整的函数调用栈。刚刚我们分析过了makeAddListener
函数,其中提到它为每个点击函数安排了一个事件任务,也就是zone.scheduleEventTask
函数的执行。这个安排事件任务函数最终其实执行的是onScheduleTask
:
onScheduleTask: function (..., task) { const currentTask = Zone.currentTask; let trace = currentTask && currentTask.data && currentTask.data[creationTrace] || []; trace = [new LongStackTrace()].concat(trace); task.data[creationTrace] = trace; }
文章开头控制台输出的完整的函数调用栈,存储在currentTask.data[creationTrace]
里面,它是一个由LongStackTrace
实例组成的数组。每次有异步任务发生时,onScheduleTask
函数便把当前函数调用栈存储记录下来,我们看看类LongStackTrace
的构造器就知道了:
class LongStackTrace { constructor() { this.error = getStacktrace(); this.timestamp = new Date(); } } function getStacktraceWithUncaughtError() { return new Error(ERROR_TAG); }
this.error
存储的便是函数调用栈,getStacktrace
函数通常调用的是getStacktraceWithUncaughtError
函数,我们看到new Error
大概就能够知道整个调用栈是如何得来的了。
本文分析的只是zone.js
能力的一个示例,如果你希望了解更多功能可以参阅官方文档。通过这个示例,希望读者能对zone.js
angular tutorial
zone.js
를 통해 코드를 실행하기 시작하면 콘솔 출력의 차이점은 무엇입니까? ? 먼저 시작 코드를 조정해 보겠습니다. 🎜rrreee🎜콘솔 출력은 다음과 같습니다. 🎜rrreee🎜비교를 통해 알 수 있습니다. zone.js
가 도입되지 않은 경우 오류 호출을 통해서만 알 수 있습니다. 버튼 2로 인해 예외가 발생한 스택 클릭 기능이 발생합니다. zone.js
를 소개한 후, 우리는 버튼 2의 클릭 기능에 의해 예외가 발생한다는 것을 알 뿐만 아니라 해당 클릭 기능이 버튼 1의 클릭 기능에 묶여 있다는 것도 알게 되었습니다. 최신 초기 애플리케이션 시작은 main
함수에 의해 트리거됩니다. 여러 비동기 작업을 지속적으로 추적하는 기능은 크고 복잡한 프로젝트에서 매우 중요합니다. 이제 zone.js
가 이를 어떻게 수행하는지 살펴보겠습니다. 🎜🎜zone.js
는 클릭 이벤트, 타이머 등과 같이 브라우저에서 제공하는 비동기 API를 대신합니다. 비동기 작업에 대한 더 강력한 제어 및 개입 기능을 보유하고 더 많은 기능을 제공할 수 있는 것은 바로 이 때문입니다. 이제 클릭 이벤트를 예로 들어 이것이 어떻게 수행되는지 살펴보겠습니다. 🎜rrreee🎜위 코드에서 proto
는 EventTarget.prototype
을 참조합니다. 이는 이 코드 줄이 addEventListener
함수를 재정의한다는 의미입니다. makeAddListener
함수가 수행하는 작업을 계속 살펴보겠습니다. 🎜rrreee🎜이 함수는 주로 두 가지 작업을 수행합니다. 하나는 브라우저 자체에서 제공하는 addEventListener
함수를 사용자 정의 함수에서 실행하는 것입니다. 또한 비동기 API에 개입하는 zone.js
의 강력한 기능에 있어서 중요한 요소이기도 합니다. 🎜🎜이제 이 글의 시작 부분에 있는 예로 돌아가 콘솔이 완전하고 완전한 함수 호출 스택을 출력할 수 있는 이유를 살펴보겠습니다. 우리는 방금 zone.scheduleEventTask
함수의 실행인 각 클릭 함수에 대해 이벤트 작업을 정렬한다고 언급한 makeAddListener
함수를 분석했습니다. 이 일정 이벤트 작업 함수는 실제로 onScheduleTask
를 실행합니다.🎜rrreee🎜기사 시작 부분에 있는 콘솔에서 출력된 전체 함수 호출 스택은 currentTask.data[creationTrace]에 저장되어 있습니다. code> - <code>LongStackTrace
인스턴스로 구성된 배열입니다. 비동기 작업이 발생할 때마다 onScheduleTask
함수는 현재 함수 호출 스택 저장소를 기록합니다. LongStackTrace
클래스의 생성자를 살펴보겠습니다. 🎜rrreee🎜 this.error는 함수 호출 스택을 저장합니다. getStacktrace
함수는 일반적으로 getStacktraceWithUncaughtError
함수를 호출합니다. 아마도 전체 호출 스택을 얻는 방법을 알 수 있을 것입니다. 🎜🎜이 글은 zone.js
기능의 예를 분석한 것입니다. 더 많은 기능을 알고 싶다면 공식 문서를 참조하세요. 이 예제를 통해 독자들이 zone.js
에 대한 전반적인 이해를 가질 수 있기를 바랍니다. 이는 Angular 변경 감지에 없어서는 안 될 초석이기도 하기 때문입니다. 이 부분에 대해서는 다음 글에서 설명하겠습니다. 🎜🎜더 많은 프로그래밍 관련 지식을 보려면 🎜프로그래밍 소개🎜를 방문하세요! ! 🎜위 내용은 Angular의 zone.js에 대한 심층 분석 및 작동 방식의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

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

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

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

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

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

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

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

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

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

뜨거운 주제











이 글은 Angular에 대한 학습을 계속하고, Angular의 메타데이터와 데코레이터를 이해하고, 그 사용법을 간략하게 이해하는 데 도움이 되기를 바랍니다.

Angular.js는 동적 애플리케이션을 만들기 위해 자유롭게 액세스할 수 있는 JavaScript 플랫폼입니다. HTML 구문을 템플릿 언어로 확장하여 애플리케이션의 다양한 측면을 빠르고 명확하게 표현할 수 있습니다. Angular.js는 코드를 작성, 업데이트 및 테스트하는 데 도움이 되는 다양한 도구를 제공합니다. 또한 라우팅 및 양식 관리와 같은 많은 기능을 제공합니다. 이 가이드에서는 Ubuntu24에 Angular를 설치하는 방법에 대해 설명합니다. 먼저 Node.js를 설치해야 합니다. Node.js는 서버 측에서 JavaScript 코드를 실행할 수 있게 해주는 ChromeV8 엔진 기반의 JavaScript 실행 환경입니다. Ub에 있으려면

이 글은 Angular의 상태 관리자 NgRx에 대한 심층적인 이해를 제공하고 NgRx 사용 방법을 소개하는 글이 될 것입니다.

앵귤러 유니버셜(Angular Universal)을 아시나요? 웹사이트가 더 나은 SEO 지원을 제공하는 데 도움이 될 수 있습니다!

인터넷의 급속한 발전과 함께 프론트엔드 개발 기술도 지속적으로 개선되고 반복되고 있습니다. PHP와 Angular는 프런트엔드 개발에 널리 사용되는 두 가지 기술입니다. PHP는 양식 처리, 동적 페이지 생성, 액세스 권한 관리와 같은 작업을 처리할 수 있는 서버측 스크립팅 언어입니다. Angular는 단일 페이지 애플리케이션을 개발하고 구성 요소화된 웹 애플리케이션을 구축하는 데 사용할 수 있는 JavaScript 프레임워크입니다. 이 기사에서는 프론트엔드 개발에 PHP와 Angular를 사용하는 방법과 이들을 결합하는 방법을 소개합니다.

이 기사는 Angular의 실제 경험을 공유하고 ng-zorro와 결합된 angualr을 사용하여 백엔드 시스템을 빠르게 개발하는 방법을 배우게 될 것입니다. 모든 사람에게 도움이 되기를 바랍니다.

각도에서 모나코 편집기를 사용하는 방법은 무엇입니까? 다음 글은 최근 비즈니스에서 사용되는 Monaco-Editor의 활용 사례를 기록한 글입니다.

이 기사에서는 Angular의 독립 구성 요소, Angular에서 독립 구성 요소를 만드는 방법, 기존 모듈을 독립 구성 요소로 가져오는 방법을 안내합니다.
