본문 바로가기
Programing/Javascript

JavaScript Promise Chaining(Promise 연쇄사용법)

by 멍멍돌이야 2022. 7. 5.
반응형

Introduction to the JavaScript promise chaining(promise chaining 란?)

경우에 따라 다음 작업이 이전 단계의 결과로 시작되는 두 개 이상의 관련된 비동기 작업을 실행하려고 합니다. 예를 들어:

 

먼저 3초 후에 숫자 10으로 확인되는 새 약속을 만듭니다.

let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(10);
    }, 3 * 100);
});
setTimeout() 함수는 비동기 작업을 시뮬레이션합니다.

그런 다음 약속의 then() 메서드를 호출합니다.

p.then((result) => {
    console.log(result);
    return result * 2;
});

then() 메서드에 전달된 콜백은 약속이 해결되면 실행됩니다. 콜백에서 약속의 결과를 표시하고 2를 곱한 새 값(result*2)을 반환합니다.

then() 메서드는 값이 값으로 확인된 새 Promise를 반환하므로 반환되는 Promise에서 다음과 같이 then() 메서드를 호출할 수 있습니다.

let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(10);
    }, 3 * 100);
});

p.then((result) => {
    console.log(result);
    return result * 2;
}).then((result) => {
    console.log(result);
    return result * 3;
});

Output:

10
20

이 예에서 첫 번째 then() 메서드의 반환 값은 두 번째 then() 메서드로 전달됩니다. 다음과 같이 then() 메서드를 계속 호출할 수 있습니다.

let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(10);
    }, 3 * 100);
});

p.then((result) => {
    console.log(result); // 10
    return result * 2;
}).then((result) => {
    console.log(result); // 20
    return result * 3;
}).then((result) => {
    console.log(result); // 60
    return result * 4;
});

Output:

10
20
60

이와 같이 then() 메서드를 호출하는 방식을 종종 약속 체인이라고 합니다.

다음 그림은 약속 체인을 보여줍니다.

 

Multiple handlers for a promise

프라미스에 대해 then() 메서드를 여러 번 호출하면 프라미스 연결이 아닙니다. 예를 들어:

let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(10);
    }, 3 * 100);
});

p.then((result) => {
    console.log(result); // 10
    return result * 2;
})

p.then((result) => {
    console.log(result); // 10
    return result * 3;
})

p.then((result) => {
    console.log(result); // 10
    return result * 4;
});

Output:

10
10
10

이 예에서는 하나의 약속에 대해 여러 핸들러가 있습니다. 이러한 핸들러에는 관계가 없습니다. 또한 독립적으로 실행되며 위의 약속 체인처럼 결과를 서로 전달하지 않습니다.

다음 그림은 여러 핸들러가 있는 프라미스를 보여줍니다.

실제로는 하나의 Promise에 대해 여러 핸들러를 사용하는 경우는 거의 없습니다.

 

Returning a Promise

then() 메서드에서 값을 반환하면 then() 메서드는 반환 값으로 즉시 확인되는 새 Promise를 반환합니다.

또한 다음과 같이 then() 메서드에서 새 약속을 반환할 수 있습니다.

let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(10);
    }, 3 * 100);
});

p.then((result) => {
    console.log(result);
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(result * 2);
        }, 3 * 1000);
    });
}).then((result) => {
    console.log(result);
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(result * 3);
        }, 3 * 1000);
    });
}).then(result => console.log(result));

Output:

10
20
60

이 예에서는 3초마다 10, 20, 60을 표시합니다. 이 코드 패턴을 사용하면 일부 작업을 순서대로 실행할 수 있습니다.

다음은 위의 예를 수정했습니다.

function generateNumber(num) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(num);
    }, 3 * 1000);
  });
}

generateNumber(10)
  .then((result) => {
    console.log(result);
    return generateNumber(result * 2);
  })
  .then((result) => {
    console.log(result);
    return generateNumber(result * 3);
  })
  .then((result) => console.log(result));

 

Promise chaining syntax

경우에 따라 순서대로 실행하려는 여러 비동기 작업이 있습니다. 또한 이전 단계의 결과를 다음 단계로 전달해야 합니다. 이 경우 다음 구문을 사용할 수 있습니다.

step1()
    .then(result => step2(result))
    .then(result => step3(result))
    ...

결과를 전달하지 않고 이전 작업의 결과를 다음 작업으로 전달해야 하는 경우 다음 구문을 사용합니다.

step1()
    .then(step2)
    .then(step3)
    ...

다음 비동기 작업을 순서대로 수행한다고 가정합니다.

  • 첫째, 데이터베이스에서 사용자를 가져옵니다.
  • 둘째, 선택한 사용자의 서비스를 가져옵니다.
  • 셋째, 사용자의 서비스에서 서비스 비용을 계산합니다.

다음 함수는 세 가지 비동기 작업을 보여줍니다.

function getUser(userId) {
    return new Promise((resolve, reject) => {
        console.log('Get the user from the database.');
        setTimeout(() => {
            resolve({
                userId: userId,
                username: 'admin'
            });
        }, 1000);
    })
}

function getServices(user) {
    return new Promise((resolve, reject) => {
        console.log(`Get the services of ${user.username} from the API.`);
        setTimeout(() => {
            resolve(['Email', 'VPN', 'CDN']);
        }, 3 * 1000);
    });
}

function getServiceCost(services) {
    return new Promise((resolve, reject) => {
        console.log(`Calculate the service cost of ${services}.`);
        setTimeout(() => {
            resolve(services.length * 100);
        }, 2 * 1000);
    });
}

다음은 약속을 사용하여 시퀀스를 직렬화합니다.

getUser(100)
    .then(getServices)
    .then(getServiceCost)
    .then(console.log);

Output:

Get the user from the database.
Get the services of admin from the API.
Calculate the service cost of Email,VPN,CDN.
300
ES2017에는 promise chaining 기술을 사용하는 것보다 더 깔끔한 코드를 작성하는 데 도움이 되는 async/await가 도입되었습니다.

이 자습서에서는 여러 비동기 작업을 순서대로 실행하는 약속 체인에 대해 배웠습니다.

 

 

 

 

Reference: https://www.javascripttutorial.net/es6/promise-chaining/

 

728x90
반응형

댓글