자 바스 크 립 트 에서 오류 가 올 바 르 게 처리 되 었 습 니 다.
본 고 는 클 라 이언 트 자 바스 크 립 트 의 오류 처 리 를 토론 할 것 입 니 다.자 바스 크 립 트 의 오류,오류 처리,비동기 코드 작성 등 을 소개 합 니 다.
자 바스 크 립 트 의 오 류 를 정확하게 처리 하 는 방법 을 살 펴 보 자.
데모 데모
본 논문 에서 사용 하 는 demo 는GitHub에서 찾 을 수 있 습 니 다.실행 한 후에 이런 페이지 가 될 것 입 니 다.
모든 단 추 는'오류(Exception)'를 일 으 키 며,이 오 류 는 버 려 진 이상 TypeError 를 모 의 합 니 다.다음은 모듈 의 정의 입 니 다.
// scripts/error.js
function error() {
var foo = {};
return foo.bar();
}
우선,이 함 수 는 빈 대상 foo 를 설명 합 니 다.주의해 야 할 것 은 bar()가 어느 곳 에서 도 정의 되 지 않 았 다 는 것 이다.다음은 이 단원 테스트 가'오류'를 일 으 킬 수 있 는 지 검증 합 니 다.
// tests/scripts/errorTest.js
it('throws a TypeError', function () {
should.throws(error, TypeError);
});
이 단원 테스트 는Mocha에서 동시에Should.js에서 테스트 성명 이 있다.Mocha 는 테스트 실행 도구 이 고 Should.js 는 단언 라 이브 러 리 입 니 다.이 단원 테스트 는 노드 에서 실행 되 며 브 라 우 저 를 사용 할 필요 가 없습니다.error()는 빈 대상 을 정의 한 다음 접근 방법 을 시도 합 니 다.bar()는 대상 내 에 존재 하지 않 기 때문에 이상 을 유발 할 수 있다.자 바스 크 립 트 와 같은 동적 언어 에서 발생 하 는 이러한 오 류 는 누구나 만 날 수 있 습 니 다!
오류 처리(1)
다음 코드 를 통 해 상기 오 류 를 처리 합 니 다.
// scripts/badHandler.js
function badHandler(fn) {
try {
return fn();
} catch (e) { }
return null;
}
이 처리 프로그램 은 fn 을 입력 매개 변수 로 한 다음 fn 은 처리 함수 내부 에서 호출 됩 니 다.유닛 테스트 는 상기 오류 처리 프로그램의 역할 을 나 타 낼 수 있 습 니 다.
// tests/scripts/badHandlerTest.js
it('returns a value without errors', function() {
var fn = function() {
return 1;
};
var result = badHandler(fn);
result.should.equal(1);
});
it('returns a null with errors', function() {
var fn = function() {
throw new Error('random error');
};
var result = badHandler(fn);
should(result).equal(null);
});
문제 가 생기 면 오류 처리 프로그램 은 null 로 돌아 갑 니 다.fn()반전 함 수 는 합 법 적 인 방법 이나 오 류 를 가리 킬 수 있 습 니 다.아래 의 클릭 이 벤트 는 이벤트 처 리 를 계속 진행 합 니 다:
// scripts/badHandlerDom.js
(function (handler, bomb) {
var badButton = document.getElementById('bad');
if (badButton) {
badButton.addEventListener('click', function () {
handler(bomb);
console.log('Imagine, getting promoted for hiding mistakes');
});
}
}(badHandler, error));
이런 처리 방식 은 코드 에 오 류 를 숨 겼 고 발견 하기 어렵다.숨겨 진 오 류 는 디 버 깅 시간 이 몇 시간 걸 릴 수 있 습 니 다.특히 스 택 을 심도 있 게 호출 하 는 다 층 솔 루 션 에서 이 오 류 는 더욱 발견 하기 어 려 울 것 이다.그래서 이것 은 매우 나 쁜 오류 처리 방식 이다.오류 처리(2)
다음은 또 다른 오류 처리 방식 이다.
// scripts/uglyHandler.js
function uglyHandler(fn) {
try {
return fn();
} catch (e) {
throw new Error('a new error');
}
}
이상 처리 방식 은 다음 과 같다.
// tests/scripts/uglyHandlerTest.js
it('returns a new error with errors', function () {
var fn = function () {
throw new TypeError('type error');
};
should.throws(function () {
uglyHandler(fn);
}, Error);
});
이상 은 잘못된 처리 프로그램 에 대해 뚜렷 한 개선 이 있 습 니 다.이곳 에 서 는 이상 하 게 스 택 을 호출 하여 거품 을 일 으 킬 것 이다.동시에 오류 가 스 택 을 펼 치 는 것 은 디 버 깅 에 매우 도움 이 됩 니 다.이상 을 던 지 는 것 외 에 해석 기 는 스 택 을 따라 다른 처 리 를 찾 을 것 이다.이것 도 창고 꼭대기 에서 오 류 를 처리 할 수 있 는 가능성 을 가 져 왔 다.그러나 이것 은 비교적 나 쁜 오류 처리 이기 때문에 우 리 는 창고 에서 원시 적 인 이상 을 한 걸음 한 걸음 거 슬러 올 라 가 야 한다.이러한 나 쁜 오류 처 리 를 사용자 정의 오류 로 끝 낼 수 있 는 대체 방안 을 사용 할 수 있다.오류 에 더 자세 한 정 보 를 추가 하면 도움 이 된다.
예 를 들 면:
// scripts/specifiedError.js
// Create a custom error
var SpecifiedError = function SpecifiedError(message) {
this.name = 'SpecifiedError';
this.message = message || '';
this.stack = (new Error()).stack;
};
SpecifiedError.prototype = new Error();
SpecifiedError.prototype.constructor = SpecifiedError;
// scripts/uglyHandlerImproved.js
function uglyHandlerImproved(fn) {
try {
return fn();
} catch (e) {
throw new SpecifiedError(e.message);
}
}
// tests/scripts/uglyHandlerImprovedTest.js
it('returns a specified error with errors', function () {
var fn = function () {
throw new TypeError('type error');
};
should.throws(function () {
uglyHandlerImproved(fn);
}, SpecifiedError);
});
지정 한 오 류 는 더 자세 한 정 보 를 추가 하고 원본 오류 메 시 지 를 유지 합 니 다.이 개선 이 있 으 면 이상 의 처 리 는 더 이상 비교적 나 쁜 처리 방식 이 아니 라 뚜렷 하고 유용 한 방식 이다.위의 처 리 를 거 쳐 우 리 는 처리 되 지 않 은 이상 도 받 았 다.다음은 브 라 우 저가 오 류 를 처리 할 때 어떤 도움 이 되 는 지 살 펴 보 자.
스 택 열기
이상 을 처리 하 는 방법 은 스 택 의 상단 에 try..catch 를 추가 하 는 것 입 니 다.
예 를 들 면:
function main(bomb) {
try {
bomb();
} catch (e) {
// Handle all the error things
}
}
그러나 브 라 우 저 는 이벤트 로 작 동 되 고 자 바스 크 립 트 의 이상 도 하나의 이벤트 입 니 다.이상 이 발생 하면 해석 기 는 실행 을 중단 하고 전 개 됩 니 다.
// scripts/errorHandlerDom.js
window.addEventListener('error', function (e) {
var error = e.error;
console.log(error);
});
이 이벤트 처리 프로그램 은 상하 문 에서 발생 하 는 모든 오 류 를 포착 합 니 다.각 목표 에서 발생 하 는 오류 사건 은 여러 종류의 오 류 를 촉발 합 니 다.코드 에 집 중 된 이런 오류 처 리 는 매우 급진 적 이다.너 는 국화 사슬 처리 방식 을 사용 하여 특정한 오 류 를 처리 할 수 있다.SOLID 원칙 을 따 르 면 단일 목적 의 오류 처리 방식 을 사용 할 수 있다.이 처리 프로그램 들 은 수시로 등록 할 수 있 으 며,해석 기 는 실행 해 야 할 처리 프로그램 을 순환 적 으로 실행 할 수 있다.코드 라 이브 러 리 는 try..catch 블록 에서 방출 할 수 있 으 며 디 버 깅 도 쉬 워 집 니 다.자 바스 크 립 트 에 서 는 오 류 를 사건 처리 로 처리 하 는 것 이 중요 하 다.포획 창고
문 제 를 해결 할 때 스 택 을 호출 하 는 것 이 매우 유용 하 며 브 라 우 저 는 이러한 정 보 를 제공 할 수 있 습 니 다.스 택 속성 은 표준 일부분 이 아니 지만 최신 브 라 우 저 는 이미 이 정 보 를 볼 수 있 습 니 다.
다음은 서버 에 오 류 를 기록 한 예제 입 니 다.
// scripts/errorAjaxHandlerDom.js
window.addEventListener('error', function (e) {
var stack = e.error.stack;
var message = e.error.toString();
if (stack) {
message += '
' + stack;
}
var xhr = new XMLHttpRequest();
xhr.open('POST', '/log', true);
// Fire an Ajax request with error details
xhr.send(message);
});
모든 오류 처 리 는 하나의 목적 을 가지 고 있 습 니 다.이렇게 하면 코드 의DRY원칙(목적 이 단일 하고 자신의 원칙 을 반복 하지 마 십시오)을 유지 할 수 있 습 니 다.브 라 우 저 에서 이벤트 처 리 를 DOM 에 추가 해 야 합 니 다.이것 은 만약 당신 이 제3자 라 이브 러 리 를 구축 하고 있다 면,당신 의 사건 은 클 라 이언 트 코드 와 공존 할 것 이라는 것 을 의미한다.window.addEventListener()가 처리 해 줄 뿐만 아니 라 기 존 사건 도 지우 지 않 습 니 다.
이것 은 서버 로그 의 캡 처 입 니 다:
명령 프롬프트 를 통 해 로 그 를 볼 수 있 지만 Windows 에 서 는 로그 가 비 동적 입 니 다.
로 그 를 통 해 어떤 상황 이 어떤 오 류 를 일 으 켰 는 지 알 수 있 습 니 다.디 버 깅 할 때 스 택 을 호출 하 는 것 도 매우 유용 하 므 로 스 택 을 호출 하 는 역할 을 과소평가 하지 마 세 요.
자바 스 크 립 트 에서 오류 정 보 는 단일 도 메 인 에 만 적 용 됩 니 다.도 메 인 을 사용 하지 않 는 스 크 립 트 를 사용 할 때 오류 에 대한 자세 한 정 보 를 볼 수 없 기 때 문 입 니 다.
하나의 해결 방안 은 오 류 를 다시 던 지고 오류 메 시 지 를 유지 하 는 것 이다.
오류 준비 가 다시 시작 되면
try {
return fn();
} catch (e) {
throw new Error(e.message);
}
전역 오류 처리 프로그램 이 나머지 작업 을 완료 합 니 다.같은 도 메 인 에 오류 처리 가 있 는 지 확인 하 십시오.원본 메시지,스 택,사용자 정의 오류 대상 을 유지 합 니 다.비동기 처리
JavaScript 는 비동기 코드 를 실행 할 때 다음 과 같은 이상 처 리 를 하면 문제 가 발생 합 니 다.
// scripts/asyncHandler.js
function asyncHandler(fn) {
try {
// This rips the potential bomb from the current context
setTimeout(function () {
fn();
}, 1);
} catch (e) { }
}
단원 테스트 를 통 해 문 제 를 보기:
// tests/scripts/asyncHandlerTest.js
it('does not catch exceptions with errors', function () {
// The bomb
var fn = function () {
throw new TypeError('type error');
};
// Check that the exception is not caught
should.doesNotThrow(function () {
asyncHandler(fn);
});
});
이 이상 은 포착 되 지 않 았 습 니 다.우 리 는 유닛 테스트 를 통 해 검증 합 니 다.코드 는 try..catch 를 포함 하고 있 지만 try..catch 문 구 는 하나의 실행 컨 텍스트 에서 만 작 동 합 니 다.이상 이 던 져 졌 을 때 해석 기 는 try..catch 에서 벗 어 났 기 때문에 이상 하 게 처리 되 지 않 았 습 니 다.Ajax 호출 도 같은 상황 이 발생 할 수 있 습 니 다.따라서 하나의 해결 방안 은 비동기 반전 에서 이상 을 포착 하 는 것 이다.
setTimeout(function () {
try {
fn();
} catch (e) {
// Handle this async error
}
}, 1);
이런 방법 은 비교적 효과 가 있 을 수 있 지만,여전히 매우 큰 개선 공간 이 있다.우선,이 try...catch block 은 전체 지역 에서 복잡 하 게 얽 혀 있 습 니 다.사실 V8 브 라 우 저 엔진 은 함수 내 에서 try..catch block 을 사용 하 는 것 을 권장 하지 않 습 니 다.V8 은 크롬 브 라 우 저 와 노드 에서 사용 하 는 자 바스 크 립 트 엔진 이다.try..catch block 을 스 택 호출 상단 으로 이동 하 는 방법 이지 만 비동기 코드 프로 그래 밍 에는 적용 되 지 않 습 니 다.
전역 오류 처 리 는 모든 컨 텍스트 에서 실 행 될 수 있 기 때문에 오류 처리 에 창 대상 을 추가 하면 코드 의 DRY 와 SOLID 원칙 을 보장 할 수 있 습 니 다.동시에 전체적인 오류 처리 도 당신 의 비동기 코드 가 매우 깨끗 하 다 는 것 을 보증 할 수 있 습 니 다.
다음은 이 이상 처리 가 서버 에 있 는 보고 내용 입 니 다.출력 내용 은 브 라 우 저 에 따라 다 를 수 있 으 니 주의 하 십시오.
오류 처리 에서 보 듯 이 오 류 는 비동기 코드 의 setTimeout()기능 에서 발생 합 니 다.
결론.
잘못된 처 리 를 할 때 문 제 를 숨 기지 말고 제때에 문 제 를 발견 하고 각종 방법 으로 문제 의 근원 을 거 슬러 올 라 가 문 제 를 해결 해 야 한다.코드 를 작성 할 때 항상 오 류 를 묻 을 수 있 지만 오류 가 발생 하 는 것 을 너무 부끄러워 하지 않 아 도 됩 니 다.문 제 를 발견 하고 더 큰 문 제 를 피 하 는 것 이 바로 우리 가 지금 해 야 할 일 입 니 다.
총결산
위 에서 말 한 것 은 편집장 이 여러분 에 게 소개 한 자 바스 크 립 트 의 잘못된 정확 한 처리 방식 소결 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.편집장 은 제때에 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[2022.04.19] 자바스크립트 this - 생성자 함수와 이벤트리스너에서의 this18일에 this에 대해 공부하면서 적었던 일반적인 함수나 객체에서의 this가 아닌 오늘은 이벤트리스너와 생성자 함수 안에서의 this를 살펴보기로 했다. new 키워드를 붙여 함수를 생성자로 사용할 때 this는...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.