PGR21.com
- PGR21 관련된 질문 및 건의는 [건의 게시판]을 이용바랍니다.
- (2013년 3월 이전) 오래된 질문글은 [이전 질문 게시판]에 있습니다.
통합 규정을 준수해 주십시오. (2015.12.25.)
Date 2016/05/18 01:29:24
Name 꼭두서니색
Subject [질문] 자바스크립트+XMLHttpRequest 질문입니다.
자바스크립트 코딩을 하고 있는데, 막히는 부분이 있어 질문드립니다.

콜백함수내부에서 변경된 값을 외부로 가져오는 문제인데요, 예를 들면

var arg1 = new Array(2);
arg1[0] = new testObj();
arg1[1] = new testObj();

function foo1(arg){
        var xhr = new XMLHttpRequest();
        var requestUri = testUri;        
        xhr.open('GET', requestUri, true);
        xhr.send();
        xhr.onreadystatechange = callback1;
        
        function callback1(e){
                if(xhr.readyState == 4 && xhr.status == 200){
                        var data = JSON.parse(xhr.responseText);
                        arg[0].name = data.name;
                }
        }
}

foo(arg1);
document.getElementByid("test").innerHTML = arg1[0].name;

이런 식으로 코드를 작성해봤는데, foo1() 내부함수인 callback1에서 변경한 arg[0].name 을 foo1() 외부에서 불러보면 함수 내부에서 변경한 값이 반영되지 않더라구요.

찾아보니 자바스크립트는 call by value만 되고 call by reference는 파라미터를 배열형으로 넘겨라..이런식으로 써있던데 저런식으로 내부함수에서 변경한 값을 완전 외부에서 가져오는 방법에 대한 설명을 제가 못찾았는지 안보여서 질문드립니다.

C는 포인터로 다 해결됐었는데 자바스크립트하려니 너무 기초적인데서 막히니 부끄럽습니다..ㅜㅜ 위같은 상황은 어떤식으로 해결해야 하는지 고수분들의 많은 조언 부탁드립니다.

통합규정 1.3 이용안내 인용

"Pgr은 '명문화된 삭제규정'이 반드시 필요하지 않은 분을 환영합니다.
법 없이도 사는 사람, 남에게 상처를 주지 않으면서 같이 이야기 나눌 수 있는 분이면 좋겠습니다."
16/05/18 02:50
수정 아이콘
원인: XMLHttpRequest가 비동기적으로 처리 되기 때문에 실행되는 순서가 (1) foo(arg1); 호출 -> (2) XMLHttpRequest로 서버 요청 -> (3) innerHTML arg1[0].name으로 설정 -> (4) 서버 응답을 받아 arg[0].name을 설정 순으로 일어나기 때문입니다. 해결 방법은 간단한데 크게 3개 정도를 들 수 있을 것 같네요.

1) XMLHttpRequest를 동기요청으로 변경: xhr.open의 세번째 인자인 true를 false로 바꿔주기. 그러면 위의 (4)가 (3)전에 완료 되어야지 순서대로 실행이 됩니다. 학교 프로젝트나 과제 수준에서는 무관하나 실무에서는 사용 하지 않는 방식입니다.
2) XHR 콜백 함수 안에서 처리: 위의 (4)번 실행 줄인 arg[0].name = data.name; 뒤에 (3)의 innerHTML을 설정하는 소스를 넣어서 서버의 응답이 설정 된다음에 실행되도록 하는 방법입니다. 아주 쉽게 수정할 수 있지만, 다른 언어 개발자들은 익숙하지 않은 방법이고, 일반적으로 많이 사용하는 방법입니다.
3) 실행될 콜백함수를 인자로 넘기기: foo1 함수에 callback 인자를 추가해서 XHR 응답 콜백 함수가 호출된 다음에 해당 함수가 호출되도록 하는 방법. 간단한 예를 들면 아래와 같습니다. 자바스크립트가 더 익숙해지면 사용하는 방법입니다.

foo1(arg1, function (arg2) {
document.getElementById("test").innerHTML = arg2[0].name;
});

foo1의 정의는 foo1(arg, callback) { 으로 변경하고, XHR의 콜백 함수 안에서는 콜백함수를 호출하면 됩니다.

function foo1(arg, callback) {
//생략
  if(xhr.readyState == 4 && xhr.status == 200){
    var data = JSON.parse(xhr.responseText);
    arg[0].name = data.name;
     callback(arg);
  }
}

자바스크립트는 이벤트 기반 비동기 처리가 많아서 C를 하다가 자바스크립트를 하면 실행 구조 자체가 많이 바뀌기 때문에 비동기처리라는 것을 신경 쓰시면 될 것 같네요. 그리고 자바스크립트는 그냥 객체를 넘겨도 상관없는데, 객체 자체를 변경하면 안되고 객체의 속성을 변경하는 것은 됩니다. C에서 포인터를 인자로 넘긴다고 생각하면 됩니다. 위의 함수에서 foo1 안에서 인자로 넘어온 arg자체를 변경하는 것은 안되지만, arg.name과 같은 객체의 속성은 그냥 변경해도 원래 객체에 반영된다는거죠.
꼭두서니색
16/05/18 08:54
수정 아이콘
상세한 답편 감사합니다. 말씀해주신것중 2번으로 했다가 코드정리하면서 3번으로 바꿨습니다. C에서의 시그널이나 인터럽트 처리 생각하니 편하더라구요 흐흐
구글에서 검색중에 님 블로그까지 갔었는데 많은 도움 받았습니다. 혹시 괜찮으시면 자바스크립트 편집기 추천 부탁드려도 될까요? 지금은 notepad++쓰는데 실수로 발생한 오타같은걸 전혀 못잡아줘서 디버깅이 세월입니다..ㅜㅜ
트루키
16/05/18 09:35
수정 아이콘
sublime text 3 , visual studio code, webstorm 중에서 웹스톰이 제일 좋지만 유료입니다.
꼭두서니색
16/05/18 12:30
수정 아이콘
찾아보니 20달러정도네요.. 크게 부담되진 않으니 일단 평가판 써봐야겠습니다. 감사합니다.
16/05/18 11:03
수정 아이콘
저는 보통 자바스크립트는 서버 환경에서 바로 작업하고 브라우져로 확인하면서 디버깅하는 것을 좋아해서 그냥 서버에서 vim으로 작업합니다.
노트북도 맥이라 그냥 터미널에서 vim쓰고요, 서버에 접속 못하는 경우 윈도우에서 작업할 때에는 sublime text를 사용합니다.
오타나 디버깅 툴 자체는 그냥 최근 브라우져들이 다 지원해주고 있는 개발자 도구를 사용하면 어디서 에러 났는지 알려주고, break도 걸 수 있어서 괜찮습니다.
꼭두서니색
16/05/18 12:32
수정 아이콘
개발자도구에서 그런것도 해주는줄은 몰랐네요. 로우레벨만 하다가 웹프로그래밍하려니 힘들었는데 좋은 정보 감사합니다!
목록 삭게로! 맨위로
번호 제목 이름 날짜 조회
83233 [질문] 홈트레이닝 질문입니다. [4] 호로2428 16/05/18 2428
83232 [질문] 보드가 제작되는과정이 궁금합니다 [4] 패스파인더1969 16/05/18 1969
83231 [질문] 인터넷에서 볼수있는 C/C++강좌 있을까요? [21] 몽유도원7015 16/05/18 7015
83230 [질문] [LOL] 6.10 패치 어떻게 보시나요? [29] 솔마4685 16/05/18 4685
83229 [질문] 멘탈을 따로 단련하는 방법이 있을까요? [9] 불타는밀밭3764 16/05/18 3764
83228 [질문] 카톡은 전화번호만으로도 누군지 알수있나요? [3] 기니피그4911 16/05/18 4911
83227 [질문] [디아2] 요즘에 해도 재밌나요? [18] 10월9일한글날3894 16/05/18 3894
83226 [질문] 핸드폰 오류질문입니다 Socceroo1774 16/05/18 1774
83225 [질문] 우리나라 역사와 세계사를 연결해서 공부할 수 있는 책이 있을까요 [7] 아리아리해2138 16/05/18 2138
83224 [질문] 엑셀 함수(날짜별 정렬) 질문입니다. [2] yeast4707 16/05/18 4707
83223 [질문] 안 쓰는 폰 팔려고 합니다. [1] 빌리진낫마이러버1607 16/05/18 1607
83222 [질문] 인천국제공항 -> 김포공항 질문입니다. [13] K52131 16/05/18 2131
83221 [질문] 고전 게임 제목 찾습니다 [3] wook982203 16/05/18 2203
83220 [질문] 네비없이 지도만 가지고 여기저기 다닐수 있나요? [18] JazzPianist4372 16/05/18 4372
83218 [질문] 야구스탯 war 에 대해 알고 싶습니다. [2] 파란무테2050 16/05/18 2050
83217 [질문] 서울에 새벽에 축구경기 볼 수 있는 펍 같은 곳 있나요? [1] 삭제됨2638 16/05/18 2638
83216 [질문] 만약 새로운 닌자 챔피언이 나온다면 어떻게 될까요? [7] 니나노나2333 16/05/18 2333
83215 [질문] 인천공항 면세지역 식당 추천 부탁드립니다. [1] JIRO2410 16/05/18 2410
83214 [질문] 오사카/교토 지금 위험한가요? [9] 2851 16/05/18 2851
83213 [질문] 연봉을 측정할때 투수 war + 타자 war 더한것보다.. [10] 마르키아르2730 16/05/18 2730
83212 [질문] 티비를 사야하는데요!(10대) [2] 우왕1925 16/05/18 1925
83211 [질문] 유머글 찾습니다. Hazle1378 16/05/18 1378
83210 [질문] GTX 550 을 쓰고 있는데요...업그레이드 후 이녀석이 의미가 있을까요? [3] 이라세오날1777 16/05/18 1777
목록 이전 다음
댓글

+ : 최근 1시간내에 달린 댓글
+ : 최근 2시간내에 달린 댓글
맨 위로