Notice
Recent Posts
Recent Comments
관리 메뉴

Developer Gonie

$.ajax(), $.getJSON() 등의 비동기 메소드를 순차처리 되도록 하는 방법 2가지(Promise, ajaxSetup) 본문

개인 공부/Javascript

$.ajax(), $.getJSON() 등의 비동기 메소드를 순차처리 되도록 하는 방법 2가지(Promise, ajaxSetup)

이대곤 2022. 9. 23. 23:24

문제가 발생하는 상황 및 원인

나는 한 번의 ajax로 대분류 카테고리명을 가져온 뒤, 그 가져온 대분류 카테고리명을 이용해

각 대분류 카테고리별 소분류 카테고리들을 가져오고자 아래와 같은 코드를 작성했었다.

그랬더니 발생한 문제는 다음과 같다.

 

바깥 ajax의 응답으로는 sucess가 잘 받아졌는데,

안쪽의 ajax에서 ajax로 사용하는 i가 이상하게 돌아가는 현상을 발견하였다.

간단히 예를들면 for문이 3번 돌아야 할 것이 2번만 도는 현상이다.

그리고 i 값도 예상했던 0 1 2 순이 아니라 0이 생략된 채로 1 2 뭐 이런식으로 돌았다.

 

ajax가 비동기 메소드다보니 이런것이 발생한 것이다.

비동기 메소드는 함수의 실행이 완료되지 않더라도 바로 다음줄로 넘어가는것이 특징이다.

$.ajax({
	url : "getLargeCategory.lcate",
	success : function(originText) {
		var lcateTextArr = [];
		var lcateNoArr = [];   
				
		var originArr = originText.split('|'); // ['mobile,1','pc/notebook,2', 'camera/dslr,3'] 
				 
		for(var i = 0; i<originArr.length; i++){
			lcateTextArr.push(originArr[i].split(',')[0]); // [mobile, pc/notebook, camera/dslr]
			lcateNoArr.push(originArr[i].split(',')[1]);   // [1, 2, 3]
		}
				
		for(var i = 0; i<lcateNoArr.length ;i++){
			$.ajax({
				url : "getSmallCategory.scate",
				data : {
					lcategoryNo : lcateNoArr[i]
				},
				success : function(originText2) {
					...
			})
		}
	}
});// outside ajax end

문제 해결책(방법1)

promise 사용(javascript에서 라이브러리 import 없이 바로 사용가능하다. 다만 이해는 조금 어렵다.)

<script src="resources/assets/js/vendor/jquery-min.js"></script>
<script>
	$(function(){
		// getting category
		$.ajax({
			url : "getLargeCategory.lcate",
			success : function(originText) { // mobile,1|pc/notebook,2|camera/dslr,3
				var lcateTextArr = []; // 모바일,PC/노트북,카메라/DSLR
				var lcateNoArr = [];   // 1,2,3
				
				var originArr = originText.split('|'); //['mobile,1','pc/notebook,2', 'camera/dslr,3'] 
				 
				for(var i = 0; i<originArr.length; i++){
					lcateTextArr.push(originArr[i].split(',')[0]); //[mobile, pc/notebook, camera/dslr]
					lcateNoArr.push(originArr[i].split(',')[1]);
					$('#cate_dropdown').append("<li id="+ originArr[i].split(',')[1] +">" 
					+ "<a href= " + "javascript:gotoSearchByCate('" + originArr[i].split(',')[0] + "')" +  " class='site-nav'>"+ originArr[i].split(',')[0] +"<i class='an an-angle-right-l'></i></a>"
					+ "</li>");
				}
				// --- makeing lcate completed 
				
				// solved async problem by promise(if we dont use promise, then loop will operate 2 times, even if loop size is 3)
				for(var i = 0; i<lcateNoArr.length ;i++){
					getScate(lcateNoArr[i])
					.then( (index) => {
						//console.log(index + "종료");
					});	
				}
				// -- inserting scate completed
				
			} // outside sucess end
		});// outside ajax end
	}); // function end		
	
	function getScate(lno){
		return new Promise((resolve, reject) => {
			$.ajax({
				url : "getSmallCategory.scate",
				data : {
					lcategoryNo : lno
				},
				success : function(originText2) { // 스마트워치,2|스마트폰,1       모니터,3|노트북,4      필름카메라,5
					console.log(originText2);
					
					var scate = [];
					var originArr2 = originText2.split('|');
					
					for(var i = 0; i<originArr2.length; i++){
						scate.push(originArr2[i].split(',')[0]);
					}
					
					$("li[id='"+ lno + "']").append("<ul class='dropdown'> </ul>");
					
					for(var i = 0; i<scate.length; i++){
						$("li[id='"+ lno + "']" + ">" + ".dropdown").append("<li>" 
								+ "<a href= " + "javascript:gotoSearchByCate('" + scate[i] + "')" +  " class='site-nav last'>" + scate[i] +"</a></li>"
								+ "</li>");	
					}
				}
			});// inside ajax end
		});// promise end
	}
</script>

문제 해결책(방법2)

$.ajax() 혹은 $.getJSON() 메소드를 호출하기 전에 $.ajaxSetup({ async: false }); 을 호출해주면

해당 메소드가 비동기가 아닌 동기화 방식으로 동작하게 되어 위에서 구현하고자 했던 바가 해결된다.

$.ajaxSetup({ async: false }); // $.getJSON() 메소드의 동기화 처리
$.getJSON("resources/only_seoul.json", function(geojson){	// json 파일관련 객체를 얻음
 	...
});
Comments