>  기사  >  웹 프론트엔드  >  Promise를 사용하여 NodeJS_node.js에서 비동기 함수 캡슐화

Promise를 사용하여 NodeJS_node.js에서 비동기 함수 캡슐화

WBOY
WBOY원래의
2016-05-16 16:13:001094검색

Node.js를 작성하는 과정에서 연속적인 IO 작업은 "피라미드 악몽"으로 이어질 수 있습니다. 콜백 함수가 여러 개 중첩되면 CommonJs의 Promise를 사용하여 비동기 함수를 캡슐화하고 통합 API를 사용하게 됩니다. 여러 콜백의 악몽을 없애기 위해.

Node.js에서 제공하는 비차단 IO 모델을 사용하면 콜백 함수를 사용하여 IO 작업을 처리할 수 있습니다. 그러나 지속적인 IO 작업이 필요한 경우 콜백 함수가 여러 번 중첩되어 코드가 매우 보기 흉하고 어려워집니다. 그리고 소위 "파멸의 피라미드"라고 불리는 오류 처리를 위한 중복 코드가 많이 있을 수 있습니다.

코드 복사 코드는 다음과 같습니다.

step1(함수(값1) {
2단계(값1, 함수(값2) {
         3단계(값2, 함수(값3) {
              4단계(값3, 함수(값4) {
// value4로 작업 수행
            });
        });
});
});

이는 실제로 Node.js의 제어 흐름에 있는 문제입니다. async 또는 eventProxy 등을 사용하는 등 이 문제에 대한 해결책이 많이 있습니다. 그러나 이 기사의 주제는 이 문제를 해결하기 위해 CommonJs 사양의 Promise를 사용하는 것입니다. 문제.

약속이란 무엇인가요?

CommonJ에는 많은 Promise 사양이 있습니다. 우리는 일반적으로 Promise의 기본 동작을 정의하는 Promise/A 사양에 대해 논의합니다.

Promise는 일반적으로 미래에 완료될 수 있는 비동기 작업을 나타내는 개체입니다. 이 작업은 성공하거나 실패할 수 있으므로 Promise 개체에는 일반적으로 보류 중, 이행됨, 거부됨이라는 세 가지 상태가 있습니다. 각각 불완전함, 성공적인 완료, 작업 실패를 나타냅니다. Promise 객체의 상태가 Pending에서 Fulfilled 또는 Rejected로 변경되면 상태를 변경할 수 없습니다.

Promise 객체에는 일반적으로 then 메소드가 있으며, 이를 통해 향후 성공 가능성이나 실패 이유 후에 반환되는 값을 조작할 수 있습니다. then 메소드는 다음과 같습니다:

promise.then(onFulfilled, onRejected)
분명히 then 메소드는 두 개의 매개변수를 받아들이는데, 이는 일반적으로 두 개의 매개변수입니다. 하나는 작업이 성공한 후 결과를 처리하는 데 사용되고 다른 하나는 이 두 함수 중 첫 번째 매개변수입니다. 각각 성공 후의 결과와 실패 이유입니다. then 메소드에 전달된 매개변수가 함수가 아닌 경우 이 매개변수는 무시됩니다.

then 메소드의 반환 값은 Promise 객체입니다. 이 기능을 사용하면 흐름 제어 효과를 얻기 위해 연쇄 호출을 수행할 수 있습니다. 여기에는 값 전송이나 오류 처리 등 세부적인 문제가 많이 있습니다. Promise의 사양은 다음과 같이 정의됩니다.

onFulfilled 또는 onRejected 함수의 반환 값이 Promise 개체가 아닌 경우 이 값은 다음 then 메서드에서 onFulfilled의 첫 번째 매개 변수로 사용됩니다. 반환 값이 Promise 개체인 경우 반환 값은 왜입니까? then 메소드의 Promise 객체
onFulfilled 또는 onRejected 함수에서 예외가 발생하면 then 메소드에 의해 반환된 Promise 객체의 상태가 Rejected로 변경됩니다. Promise 객체가 then을 호출하면 Error 객체가 onRejected 함수의 첫 번째 매개변수로 사용됩니다.
Promise 상태가 Fulfilled 가 되고 then 메소드에 onFulfilled 함수가 제공되지 않으면 then 메소드에서 반환된 Promise 객체 상태는 Fulfilled 가 되며 성공적인 결과는 이전 Promise의 결과가 됩니다. Rejected의 경우에도 마찬가지입니다.
또한 onFulfilled 및 onRejected는 비동기적으로 실행됩니다.

표준 구현: q

위는 Promise의 사양이며 우리에게 필요한 것은 구현입니다. q는 Promise/A에 대한 더 나은 구현 사양을 갖춘 라이브러리입니다.

먼저 Promise 객체를 생성해야 합니다. Promise 객체 생성에 대한 사양은 Promise/B에 있습니다. 여기서는 자세한 설명을 생략하고 코드만 살펴보겠습니다.

코드 복사 코드는 다음과 같습니다.

함수(플래그){
         var defer = q.defer();
             fs.readFile("a.txt", function(err, data){
If(err) defer.reject(err);
                 else defer.resolve(data);
            });
                return defer.promise;
}

대부분의 Promise 구현은 Promise 속성을 사용하여 defer 객체를 생성하여 값을 성공적으로 얻은 경우 defer.reject(value)가 호출됩니다. )가 호출됩니다. 마지막으로 defer의 promise 속성을 반환합니다. 이 프로세스는 defer.resolve를 호출하여 Promise 상태를 Fulfilled로 변경하고 defer.reject를 호출하여 Promise 상태를 Rejected로 변경하는 것으로 이해할 수 있습니다.

일련의 연속적인 비동기 메서드에 직면했을 때 Promise를 사용하여 아름다운 코드를 작성하는 방법은 무엇입니까? 아래 예를 살펴보십시오.

코드 복사 코드는 다음과 같습니다.

promise0.then(함수(결과){
               // 뭔가를 합니다
        결과 반환
}).then(함수(결과) {
              // 뭔가를 합니다
          약속1 반환;                                        }).then(함수(결과) {
              // 뭔가를 합니다
}).catch(함수(예) {
console.log(예);
}).finally(함수(){
console.log("최종");
});

위 코드에서 then 메소드는 OnFulfilled만 허용하고 catch 메소드는 실제로 then(null, OnRejected)입니다. 이 경우 일련의 비동기 메소드가 항상 값을 성공적으로 반환하는 한 코드는 다음과 같습니다. 하향식으로 실행하면 비동기 메서드 중 하나라도 실패하거나 예외가 발생하면 CommonJs Promise 사양에 따라 catch의 함수가 실행됩니다. q는 또한 문자 그대로 이해하기 쉬운 finally 메소드를 제공합니다. 즉, 해결 또는 거부에 관계없이 finally의 함수가 실행됩니다.

좋은 것 같습니다. 코드가 유지 관리하기 쉽고 아름답습니다. 동시성을 원한다면 어떨까요?

코드 복사 코드는 다음과 같습니다.
​ q.all([promise0, promise1, promise2]).spread(function(val0, val1, val2){
console.log(인수);
                    }).then(function(){
console.log("완료");
                  }).catch(function(err){
console.log(err);
                });

Q는 동시성을 위한 API도 제공하며, then의 체인 스타일을 계속 사용하기 위해 all 메소드를 호출하고 Promise 배열을 전달합니다. Node.js의 기본 API를 Promise로 변환하여 코드 형식을 통일할 수 있는 q.nfbind 같은 것도 있는데, 이 역시 매우 좋습니다. 여기서는 더 많은 API에 대해 자세히 설명하지 않습니다.

결론

이 기사에서는 Node.js 제어 흐름 문제를 해결하기 위해 Promise를 사용하는 방법을 주로 소개하지만 Promise는 프런트 엔드에도 적용될 수 있으며 기본 API 지원을 제공합니다. Promise가 유일한 솔루션은 아니라는 점을 지적해야 합니다. async도 좋은 선택이며 보다 친숙한 동시성 제어 API를 제공합니다. 그러나 비동기 메서드로 함수를 캡슐화할 때 Promise가 더 많은 이점을 제공한다고 생각합니다.

자, 이번 글은 여기서 마치겠습니다. 모두에게 도움이 되었으면 좋겠습니다.

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