두 가지 이상의 async(비동기) 타입 ajax를 호출하고, 동시에 제어하고자 할 때 혹은 그 외에 복수개의 비동기처리를 다루기 위한 방법에 대해 알아봅니다.
(두 가지 이상의 중요한 ajax 응답이 모두 도착할 때까지, 프로그레스 바를 출력해두기 위해서 사용하는 등의 동작)
Promise 함수에 대한 제어이며, Promise에 대한 사전지식이 필요합니다.
0. 비동기 함수 예제
setTimeout은 JavaScript에 내장된 비동기 함수입니다. 각각 1초, 3초 동작시간을 갖는 두 함수를 통해 각 함수들의 응답에 따른 제어함수의 수행동작을 알아봅니다.
아래 예제에서는 각 비동기 함수들의 반환값(resolve, reject)를 바꿔가며 수행한 결과를 확인합니다.
[소스코드]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | /** * 동작시간 : 1초 * * @returns */ let resolveAtfer1Seconds = function(){ console.log('(Start) 1 Second ...'); return new Promise((resolve, reject)=>{ setTimeout(function(){ console.log('(End) 1 Second ...'); resolve(`(resolve) ${resolveAtfer1Seconds.name}`); // reject(`(reject) ${resolveAtfer1Seconds.name}`); }, 1000); }); } /** * 동작시간 : 3초 * * @returns */ let resolveAtfer3Seconds = function(){ console.log('(Start) 3 Second ...'); return new Promise((resolve, reject)=>{ setTimeout(function(){ console.log('(End) 3 Second ...'); resolve(`(resolve) ${resolveAtfer3Seconds.name}`); // reject(`(reject) ${resolveAtfer3Seconds.name}`); }, 3000); }); } |
1. Promise.all()
- 매개변수 타입 : Promise 객체를 원소로 갖는 배열
- 동작시점 (then) : 인자로 전달된 모든 Promise가 성공응답된 경우
- 예외처리 (catch) : 그 외 대상 Promise가 하나라도 reject된 경우 등의 실패
[소스코드]
1 2 3 4 5 6 | /* 1. [all] 인자의 모든 프로미스가 성공적으로 이행된 경우 (그 외는 오류처리됨.)*/ Promise.all([resolveAtfer3Seconds(), resolveAtfer1Seconds()]).then((value)=>{ console.log(`Result : ${value}`); }).catch((error)=>{ console.log(`Error : ${error}`); }); |
[결과 : 성공]
- 각각 1,3초로 동작하는 비동기 함수가 모두 종료된 후에 then절 수행
- 실패응답을 한 Promise가 먼저 응답되어, 오류처리(catch)된 모습
- 0번의 예제에서 resolve 주석처리 후 reject로 반환
[디버깅]
[결과 : 실패]
2. Promise.allSettled()
- 비동기 함수의 성공, 실패와 관련없이 모두 이행된 시점에 동작함.
- 매개변수 타입 : Promise 객체를 원소로 갖는 배열
- 응답변수 타입 : 각 Promise 객체 (resolve, reject 반환값이 아님.)
- 동작시점 (then) : 인자로 전달된 모든 Promise 객체가 이행되거나 거부되어 완료된 시점.
- 모든 Promise가 rejected되어도 then절이 수행됨.
[소스코드]
1 2 3 4 | /* 2. [allSettled] 인자의 모든 프로미스가 이행 혹은 거부되어 완료된 경우 */ Promise.allSettled([resolveAtfer3Seconds(), resolveAtfer1Seconds()]).then((value)=>{ console.log(`Result : ${value}`); }); |
[결과]
- then절의 value(결과값)이 object타입으로 리턴됨을 확인. (아래 디버깅란 확인)
- 아래 사진은 위 소스코드의 then절 value 인자에 대한 디버깅 값입니다.
1초 동작하는 비동기함수(resolveAtfer1Seconds)는 rejected되어 먼저 처리되었지만,
3초 동작하는 비동기함수(resolveAtfer3Seconds) 까지 응답되고 나서야 then절이 수행됨을 확인할 수 있습니다.
3. Promise.any()
- 복수개 비동기 함수 중 하나라도 성공한 경우.
- 매개변수 타입 : Promise 객체를 원소로 갖는 배열
- 응답변수 타입 : 각 Promise 객체 (resolve, reject 반환값이 아님.)
- 동작시점 (then) : 전달된 Promise 객체 중 먼저 성공응답(resolve)이 전달된 경우.
- 예외처리 (catch) : 모든 Promise 객체가 실패응답(rejected)이 전달된 경우.
- 먼저 실패(reject) 응답을 수신한 경우 무시되고 성공(resolve)응답이 올 때 까지 기다림.
[소스코드]
1 2 3 4 5 6 7 8 9 10 11 | /** * 3. [any] 인자의 하나의 프로미스라도 성공응답된 경우 * * 먼저온 reject는 무시함. * 모두 reject되면 오류발생 */ Promise.any([resolveAtfer3Seconds(), resolveAtfer1Seconds()]).then((value)=>{ console.log(`Result : ${value}`); }).catch((error)=>{ console.log(`Error : ${error}`); }); |
[결과]
- 위 예제 중 1초 동작함수는 reject 반환, 3초 동작함수는 resolve로 수행
- 위 예제 중 1초 동작함수는 reject 반환, 3초 동작함수는 resolve로 수행
- 먼저 수행된 reject응답이 무시됨을 확인.
4. Promise.race()
- 복수개 비동기 함수 중 하나라도 이행완료된 경우 (성공,실패 여부없이)
- 매개변수 타입 : Promise 객체를 원소로 갖는 배열
- 응답변수 타입 : 각 Promise 객체 (resolve, reject 반환값이 아님.)
- 동작시점 (then) : 최초에 응답된 이행결과 (reject)
- 예외처리 (catch) : 최초에 응답된 실패결과 (reject)
- 먼저 수행된 Promise의 결과만 반환처리함.
[소스코드]
1 2 3 4 5 6 7 8 9 10 11 | /** * 4. [race] 먼저 완료되는 프로미스값을 반환함. * * 앞 순서의 promise 결과로 리턴값이 정해짐. (resolve, reject 모두) * 나머지 프로미스도 수행하지만 */ Promise.race([resolveAtfer1Seconds(), resolveAtfer3Seconds() ]).then((value)=>{ console.log(`Result : ${value}`); }).catch((error)=>{ console.log(`Error : ${error}`); }); |
[결과 : 성공]
- 작업시간이 1초인 비동기함수(resolveAtfer1Seconds)의 응답이 수행됨.
- 작업시간이 1초인 비동기함수(resolveAtfer1Seconds)의 응답이 수행됨.
[출처(MDN) : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise]
0 댓글