Node.js를 작성하는 과정에서 지속적인 IO 작업은 "피라미드 악몽"으로 이어질 수 있습니다. 콜백 함수의 다중 중첩은 코드를 유지하기 어렵게 만듭니다. CommonJS의 약속은 비동기 기능을 캡슐화하고 통합 체인 API를 사용하여 여러 콜백의 악몽을 제거하는 데 사용됩니다.
Node.js에서 제공하는 비 블로킹 IO 모델을 사용하면 콜백 기능을 사용하여 IO 작업을 처리 할 수 있지만 연속 IO 작업이 필요할 때 콜백 기능이 여러 번 중첩되며 코드가 아름답 지 않으며 유지하기가 쉽지 않으며 오류 처리를위한 많은 반복 코드가있을 수 있습니다.
코드 사본은 다음과 같습니다.
STEP1 (함수 (value1) {
step2 (value1, function (value2) {
step3 (value2, function (value3) {
step4 (value3, function (value4) {
// value4로 무언가를합니다
});
});
});
});
이것은 실제로 Node.js의 제어 흐름의 문제입니다. 이 문제에 대한 Async, EventProxy 등을 사용하는 것과 같은 많은 해결책이 있습니다. 그러나이 기사의 주제는 CommonJS 사양에 약속을 사용 하여이 문제를 해결하는 것입니다.
약속이란 무엇입니까?
CommonJS에 대한 많은 유형의 약속 사양이 있습니다. 우리는 일반적으로 약속/A+ 사양에 대해 논의하며, 이는 약속의 기본 행동을 정의합니다.
약속은 일반적으로 미래에 완료 될 수있는 비동기 작업을 나타내는 대상입니다. 이 작업은 성공하거나 실패 할 수 있으므로 약속 대상에는 일반적으로 보류, 이행 및 거부 된 3 개의 상태가 있습니다. 이는 각각 미완성, 성공적인 완료 및 운영 실패를 나타냅니다. 약속의 상태가 보류 중이에서 이행 또는 거부로 변경되면 상태를 다시 변경할 수 없습니다.
약속 객체에는 일반적으로 당시 방법이있어서 미래에 성공한 후 반환 된 값 또는 실패 이유를 작동시킬 수 있습니다. 이 방법은 다음과 같습니다.
약속.
당시 메소드는 일반적으로 두 가지 함수 인 두 개의 매개 변수를 수락하는 것이 명백하며, 하나는 작업이 성공한 후 결과를 처리하는 데 사용되며 다른 하나는 작동 실패의 원인을 처리하는 데 사용됩니다. 이 두 함수의 첫 번째 매개 변수는 성공과 실패의 원인 이후의 결과입니다. 당시 메소드가 함수가 아닌 경우이 매개 변수는 무시됩니다.
당시 메소드의 반환 값은 약속 객체이며,이를 통해 우리는 콜을 체인 한 다음 프로세스 제어의 효과를 달성 할 수 있습니다. 여기에는 값 전송 또는 오류 처리와 같은 많은 세부 사항이 있습니다. 약속 사양은 다음과 같이 정의됩니다.
성취 된 또는 퇴적 된 함수의 반환 값은 약속 객체가 아니며 값은 다음 메소드에서 만료 된 첫 번째 매개 변수로 사용됩니다. 반환 값이 약속 객체 인 경우, 당시 메소드의 반환 값이 약속 대상이 될 수있는 방법
성취 된 기능에 예외가 발생하거나 반사 된 함수에서 발생하면 당시 반환 된 약속 객체의 상태가 거부되도록 변환됩니다. 약속 객체가 호출되면 오류 객체는 onerejected 함수의 첫 번째 매개 변수로 사용됩니다.
약속 상태가 충족되고 당시 방법으로 성취 된 함수가 제공되지 않으면 당시 방법으로 반환 된 약속 객체 상태가 충족되고 성공적인 결과는 이전 약속의 결과입니다. 거부에 대해서도 마찬가지입니다.
추가하기 위해, 성취 된 채로 및 재사용 된 것은 모두 비동기식으로 실행됩니다.
사양 구현 : Q
위의 것은 약속의 지정에 관한 것이며, 우리가 필요로하는 것은 구현입니다. Q는 Promise/A+에 대한 더 나은 구현 사양을 가진 라이브러리입니다.
우선, 우리는 약속 객체를 만들어야합니다. 약속 대상의 생성을위한 사양은 약속에 있습니다. 여기에 자세히 설명하지 않고 코드를 추가하십시오.
코드 사본은 다음과 같습니다.
함수 (플래그) {
var defer = q.defer ();
fs.ReadFile ( "a.txt", function (err, data) {
if (err) defer.reject (err);
else defer.resolve (data);
});
리턴 연기.
}
대부분의 약속 구현은 약속의 창출에서 유사합니다. 값이 성공적으로 얻어지면 약속 속성이있는 연기 객체를 만들어서 DEFER.RESOLBE (value)가 호출됩니다. 이 절
일련의 지속적인 비동기 방법에 직면 할 때 약속을 사용하여 아름다운 코드를 어떻게 쓸 수 있습니까? 다음 예를 살펴보십시오.
코드 사본은 다음과 같습니다.
약속 0. 그런데 (기능 (결과) {
// dosomething
반환 결과;
}). 그런 다음 (함수 (결과) {
// dosomething
약속 1;
}). 그런 다음 (함수 (결과) {
// dosomething
}). catch (function (ex) {
Console.log (예);
}). 마지막으로 (function () {
Console.log ( "최종");
});
위의 코드에서 당시 메소드는 완성 된 채취 만 허용하며 캐치 메소드는 실제로 (NULL, ON REJECTED)입니다. 이런 식으로, 일련의 비동기 방법이 항상 값을 성공적으로 리턴하는 한, 코드는 폭포 스타일로 하향으로 실행됩니다. 비동기 방법이 실패하거나 예외가 발생하면 CommonJS Promise 사양에 따라 캐치의 기능이 실행됩니다. Q는 또한 최종적으로 이해하기 쉬운 방법을 제공합니다. 즉 말 그대로 이해하기 쉽습니다. 즉, 해결하거나 거부하든 마지막으로 기능이 실행됩니다.
좋아 보인다. 코드가 더 유지되고 아름답다. 그래서 동시성을 원한다면 어떻게해야합니까?
코드 사본은 다음과 같습니다.
Q.all ([Promise0, Promise1, Promise2]). Spread (함수 (Val0, Val1, Val2) {
Console.log (인수);
}). 그런 다음 (function () {
Console.log ( "완료");
}). catch (function (err) {
Console.log (err);
});
Q는 또한 동시성에 대한 API를 제공하여 모든 방법을 호출하고 Promise Array를 전달하면 당시의 체인 스타일을 계속 사용할 수 있습니다. q.nfbind 등과 같은 좋은 것은 Node.js의 기본 API를 코드 형식을 통합하기위한 약속으로 변환 할 수 있습니다. 더 많은 API는 여기에 자세히 설명되지 않습니다.
결론적으로
이 기사는 주로 Node.js Control 흐름 문제를 해결하기 위해 약속의 사용을 소개하지만 프론트 엔드에도 약속을 적용 할 수도 있습니다. EmcaScript6은 기본 API 지원을 제공했습니다. 약속이 유일한 솔루션이 아니라는 점을 지적해야합니다. Async는 또한 좋은 선택이며보다 친근한 동시성 제어 API를 제공하지만, 비동기 방법으로 기능을 캡슐화 할 때 약속은 더 많은 장점이 있다고 생각합니다.
좋아, 그게이 기사의 전부입니다. 모든 사람에게 도움이되기를 바랍니다.