웹 프론트엔드 JS 튜토리얼 Angular의 zone.js에 대한 심층 분석 및 작동 방식

Angular의 zone.js에 대한 심층 분석 및 작동 방식

Feb 07, 2022 am 10:09 AM
angular

이 기사에서는 Angular의 zone.js를 살펴보고, 예제를 통해 zone.js의 기능을 보여주고, 그 뒤에 있는 작동 원리를 간략하게 분석합니다. 모든 사람에게 도움이 되기를 바랍니다.

Angular의 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(&#39;click&#39;, bindSecondButton);
  }
  function bindSecondButton() {
    b2.addEventListener(&#39;click&#39;, throwError);
  }
  function throwError() {
    throw new Error(&#39;aw shucks&#39;);
  }
  main();
</script>
로그인 후 복사

这是一个简单的 HTML 页面。页面加载时会给第一个按钮添加点击事件,其点击事件函数的功能是给第二个按钮添加点击事件,而第二个按钮的点击事件函数功能是抛出一个异常。我们依次点击第一个按钮和第二个按钮,控制台显示如下:

(索引):26 Uncaught Error: aw shucks
    at HTMLButtonElement.throwError ((索引):26:13)
로그인 후 복사

但是如果我们通过zone.js启动运行代码,控制台输出会有什么不同呢,我们先调整启动代码:

  Zone.current.fork(
      {
        name: &#39;error&#39;,
        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.jsangular tutorial

"]

Zone이 무엇인가요? 공식 문서에서는 다음과 같이 설명합니다. Zone은 여러 비동기 작업을 포괄하는 실행 컨텍스트입니다. 간단히 말해서 Zone은 비동기 작업을 가로채거나 추적하는 특히 강력한 기능을 가지고 있습니다. 아래에서는 예를 사용하여 그 기능을 보여주고 그 뒤에 있는 작동 원리를 간략하게 분석합니다. rrreee

이것은 간단한 HTML 페이지입니다. 페이지가 로드되면 첫 번째 버튼에 클릭 이벤트가 추가됩니다. 클릭 이벤트 기능의 기능은 두 번째 버튼에 클릭 이벤트를 추가하는 것이고, 두 번째 버튼의 클릭 이벤트 기능은 이벤트를 발생시키는 것입니다. 예외. 첫 번째 버튼과 두 번째 버튼을 차례로 클릭하면 콘솔에 다음과 같이 표시됩니다. 🎜rrreee🎜그러나 zone.js를 통해 코드를 실행하기 시작하면 콘솔 출력의 차이점은 무엇입니까? ? 먼저 시작 코드를 조정해 보겠습니다. 🎜rrreee🎜콘솔 출력은 다음과 같습니다. 🎜rrreee🎜비교를 통해 알 수 있습니다. zone.js가 도입되지 않은 경우 오류 호출을 통해서만 알 수 있습니다. 버튼 2로 인해 예외가 발생한 스택 클릭 기능이 발생합니다. zone.js를 소개한 후, 우리는 버튼 2의 클릭 기능에 의해 예외가 발생한다는 것을 알 뿐만 아니라 해당 클릭 기능이 버튼 1의 클릭 기능에 묶여 있다는 것도 알게 되었습니다. 최신 초기 애플리케이션 시작은 main 함수에 의해 트리거됩니다. 여러 비동기 작업을 지속적으로 추적하는 기능은 크고 복잡한 프로젝트에서 매우 중요합니다. 이제 zone.js가 이를 어떻게 수행하는지 살펴보겠습니다. 🎜🎜zone.js는 클릭 이벤트, 타이머 등과 같이 브라우저에서 제공하는 비동기 API를 대신합니다. 비동기 작업에 대한 더 강력한 제어 및 개입 기능을 보유하고 더 많은 기능을 제공할 수 있는 것은 바로 이 때문입니다. 이제 클릭 이벤트를 예로 들어 이것이 어떻게 수행되는지 살펴보겠습니다. 🎜rrreee🎜위 코드에서 protoEventTarget.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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

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

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

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

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

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

Angular의 메타데이터와 데코레이터에 대해 이야기해 보겠습니다. Angular의 메타데이터와 데코레이터에 대해 이야기해 보겠습니다. Feb 28, 2022 am 11:10 AM

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

Ubuntu 24.04에 Angular를 설치하는 방법 Ubuntu 24.04에 Angular를 설치하는 방법 Mar 23, 2024 pm 12:20 PM

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

각도 학습 상태 관리자 NgRx에 대한 자세한 설명 각도 학습 상태 관리자 NgRx에 대한 자세한 설명 May 25, 2022 am 11:01 AM

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

Angular의 서버 측 렌더링(SSR)을 탐색하는 기사 Angular의 서버 측 렌더링(SSR)을 탐색하는 기사 Dec 27, 2022 pm 07:24 PM

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

프론트엔드 개발에 PHP와 Angular를 사용하는 방법 프론트엔드 개발에 PHP와 Angular를 사용하는 방법 May 11, 2023 pm 04:04 PM

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

Angular + NG-ZORRO로 백엔드 시스템을 빠르게 개발 Angular + NG-ZORRO로 백엔드 시스템을 빠르게 개발 Apr 21, 2022 am 10:45 AM

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

각도에서 monaco-editor를 사용하는 방법에 대한 간략한 분석 각도에서 monaco-editor를 사용하는 방법에 대한 간략한 분석 Oct 17, 2022 pm 08:04 PM

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

Angular의 독립 구성요소에 대한 간략한 분석 및 사용 방법 알아보기 Angular의 독립 구성요소에 대한 간략한 분석 및 사용 방법 알아보기 Jun 23, 2022 pm 03:49 PM

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

See all articles