21 - Promise 객체

7167 단어
1. Promise의 의미
Promise는 비동기 프로그래밍의 해결 방안으로 전통적인 해결 방안인 리셋 함수와 이벤트보다 더욱 합리적이고 강력하다.
이른바 Promise란 쉽게 말하면 하나의 용기로 그 안에 미래에 끝날 사건(보통 비동기적인 조작)의 결과가 보존되어 있다.문법적으로 Promise는 비동기적인 조작에 대한 정보를 얻을 수 있는 대상이다.
Promise 대상은 세 가지 상태가 있는데 그것이 바로 pending (진행 중),fulfilled (성공),rejected (실패) 이다.
Promise 대상의 상태가 바뀔 수 있는 것은 두 가지입니다. pending에서fulfilled로 바뀔 수 있고, pending에서rejected로 바뀔 수 있습니다.이 두 가지 상황이 발생하기만 하면 상태가 응고되고 더 이상 변하지 않으며 이 결과를 계속 유지할 것이다. 이때를 Resolved(정형화)라고 부른다.
만약 어떤 사건이 끊임없이 반복된다면, 일반적으로 Stream 모드를 사용하는 것은 프로미스를 배치하는 것보다 더 좋은 선택이다.
2. 기본용법
Promise 객체는 Promise 인스턴스를 생성하는 데 사용되는 구조 함수입니다.
Promise 구조 함수는 하나의 함수를 매개 변수로 받아들인다. 이 함수의 두 매개 변수는 각각 Resolve와 Reject이다.이러한 함수는 JavaScript 엔진에서 직접 배포하지 않고도 사용할 수 있는 두 가지 함수입니다.
resolve 함수의 역할은Promise 대상의 상태를'미완성'에서'성공'(즉pending에서resolved)으로 바꾸고 비동기 조작이 성공할 때 호출하며 비동기 조작의 결과를 매개 변수로 전달하는 것이다.프로젝트 함수의 역할은 Promise 대상의 상태를 '미완성' 에서 '실패' (즉 pending에서 Rejected) 로 바꾸고, 비동기 작업이 실패할 때 호출하며, 비동기 작업이 보고한 오류를 매개 변수로 전달하는 것입니다.
const promise = new Promise(function(resolve, reject) {
    // ...
    if ( /*   */) {
        resolve(value);
    } else {
        reject(error);
    }
});

Promise 실례가 생성된 후, then 방법으로 각각 Resolved 상태와 Rejected 상태의 리셋 함수를 지정할 수 있습니다.
promise.then(function(value) {
    // success
}, function(error) {
    // failure
});

then 방법은 두 개의 리셋 함수를 매개 변수로 받아들일 수 있다.첫 번째 리셋 함수는 Promise 대상의 상태가 Resolved로 변할 때 호출되고, 두 번째 리셋 함수는 Promise 대상의 상태가 Rejected로 변할 때 호출된다.그 중에서 두 번째 함수는 선택할 수 있는 것이기 때문에 반드시 제공해야 하는 것은 아니다.두 함수 모두 Promise 객체에서 전송된 값을 매개변수로 받아들입니다.
3. Promise 실행 순서
let promise = new Promise(function(resolve, reject) {
    console.log(1);
    resolve();
    reject();
});
promise.then(function() {
    console.log(2);
}, function() {
    console.log(3);
});
console.log(4);
// 1
// 4
// 2   3

new Promise((resolve, reject)=>{
    resolve(1);  //  
    console.log(2);
}).then(r => {
    console.log(r);
});
// 2
// 1

4. 비동기적으로 그림을 불러오는 예
function loadImageAsync(url) {
    return new Promise(function(resolve, reject) {
        const image = new Image();
        image.src = url;
        image.onload = function() {
            resolve(image);
        };
        image.onerror = function() {
            reject(new Error('Could not load image'));
        };
    });
}

그림 URL을 불러오는 데 성공하면 Resolve 방법을 사용하고, 그렇지 않으면 Reject 방법을 사용합니다.
loadImageAsync(url).then(function(oImg) {
    console.log(oImg);
}, function(err) {
    console.log(err);
});

5. Promise 구현 Ajax의 예제 캡슐화 XMLHttpRequest:
const getJSON = function(url) {
    const promise = new Promise(function(resolve, reject){
        const client = new XMLHttpRequest();
        client.open("GET", url);
        client.onreadystatechange = function() {
            if (this.readyState !== 4) {
                return;
            }
            if (this.status === 200) {
                //  , resolve()
                resolve(this.response);
            } else {
                //  reject()
                reject(new Error(this.statusText));
            }
        };
        client.responseType = 'json';
        client.setRequestHeader('Accept', 'application/json');
        client.send();
    });
    return promise;
}

getJSON('url').then(function(res) {
    console.log(res);
}, function(error) {
    console.log(error);
});

resolve 함수와reject 함수를 호출할 때 인자가 있으면, 인자는 리셋 함수에 전달됩니다.Reject 함수의 매개 변수는 일반적으로 Error 객체의 인스턴스로 버퍼링 오류를 나타냅니다.resolve 함수의 매개 변수는 정상적인 값 이외에 다른 Promise 실례일 수도 있습니다. 예를 들어 아래와 같습니다.
const p1 = new Promise(function(resolve, reject){});
const p2 = new Promise(function(resolve, reject){
    resolve(p1);  // resolve Promise 
});

6, then () 방법
Promise 실례는then 방법을 가지고 있다. 즉,then 방법은 원형 대상인Promise에 정의된 것이다.prototype에 있는이 기능은 Promise 인스턴스에 상태 변경 시 콜백 함수를 추가하는 것입니다.앞에서 말했듯이 then 방법의 첫 번째 매개 변수는 Resolved 상태의 리셋 함수이고 두 번째 매개 변수(선택 가능)는 Rejected 상태의 리셋 함수이다.
n 방법은 새로운 Promise 실례를 되돌려줍니다. (원래 그 Promise 실례가 아닙니다.)따라서 체인식 쓰기, 즉then 방법 뒤에 다른then 방법을 사용할 수 있다.
체인식then을 사용하면 순서대로 호출되는 리셋 함수를 지정할 수 있습니다.이때 앞의 리셋 함수는 프로미스 대상(즉 비동기적인 조작이 있음)을 되돌릴 수 있다. 이때 뒤의 리셋 함수는 이 프로미스 대상의 상태가 바뀌기를 기다려야 호출된다.
promise1.then(()=>{
    console.log('promise1  ');
    return promise2;  //  promise 
}, ()=>{
    console.log('promise1  ');
}).then(()=>{
    console.log('promise2  ');
    return promise3;  //  promise 
}, ()=>{
    console.log('promise2  ');
}).then(()=>{
    console.log('promise3  ');
}, ()=>{
    console.log('promise3  ');
});

7、catch()
Promise.prototype.catch 방법은.오류 발생 시 리셋 함수를 지정하는 데 사용되는 null,rejection 별명입니다.또한then 방법이 지정한 리셋 함수는 실행 중 오류가 발생하면catch 방법에 의해 포착됩니다.
프로미스 대상의 오류는'거품'성격을 띠고 있어 포획될 때까지 뒤로 전달된다.실수는 항상 다음catch 문장에 포착된다는 뜻이다.
promise.then(()=>{
    console.log();
}).catch((err)=>{
    console.log(err);
});

8,finally ()finally 방법은 Promise 대상의 마지막 상태가 어떻든지 간에 실행할 동작을 지정하는 데 사용됩니다.
promise.then(res => {
    //  
}).catch(err => {
    //  
}).finally(()=> {
    //  
});

9、Promise.all() Promise.all 방법은 여러 개의 Promise 실례를 새로운 Promise 실례로 포장하는 데 사용됩니다.
const p = Promise.all([p1, p2, p3]);

p의 상태는 p1, p2, p3에 의해 결정되고 두 가지 상황으로 나뉜다.(1) p1, p2, p3의 상태가fulfilled로 변해야만 p의 상태가fulfilled로 변할 수 있다. 이때 p1, p2, p3의 반환값은 하나의 수조를 구성하여 p의 리셋 함수에 전달된다.(2) p1, p2, p3 중 하나만rejected가 있으면 p의 상태는rejected가 되고 이때 첫 번째reject의 실례적인 반환값은 p의 리셋 함수에 전달된다.
const promiseArr = [1,2,3,4,5].map(function(id) {
    return new Promise(function(resolve, reject) {
        // ...
        resolve(id);
    });
});

Promise.all () 는 매개 변수로 promise 객체 그룹을 수신합니다.
Promise.all(promiseArr).then(function(arr) {
    // ...
}).catch(function(err){
    console.log(err);
});

10、Promise.race() Promise.race 방법 역시 여러 개의 Promise 실례를 하나의 새로운 Promise 실례로 포장하는 것이다.
const p = Promise.race([p1, p2, p3]);

위 코드에서 p1, p2, p3 중 하나의 실례가 먼저 상태를 바꾸면 p의 상태는 따라서 바뀐다.먼저 바뀐 Promise 실례의 반환값은 p의 리셋 함수에 전달됩니다.
11、Promise.resolve() Promise.기존 객체를 Promise 객체로 변환하기 위해 resolve() 사용
다음 코드는 jQuery에서 생성한 deferred 대상을 새로운 Promise 대상으로 변경합니다.
const jsPromise = Promise.resolve($.ajax('/whatever.json'));

Promise.resolve('foo');
//  
new Promise(resolve => resolve('foo'));

12、Promise.reject() Promise.reject(reason) 방법도 새로운 Promise 실례를 되돌려줍니다. 이 실례의 상태는 Rejected입니다.
const p = Promise.reject(' ');
//  
const p = new Promise((resolve, reject) => reject(' '));

p.then(null, str => {
    console.log(str);
});

13、Promise.try() Promise.try는 아날로그try 코드 블록, 예를 들어promise.catch가 시뮬레이션한 것은catch 코드 블록입니다.
Promise.try(database.users.get({id:1})).then().catch();

참조 링크: 응우옌 이펑 ES6 자습서
끝!!!

좋은 웹페이지 즐겨찾기