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
수정 아이콘
개발자도구에서 그런것도 해주는줄은 몰랐네요. 로우레벨만 하다가 웹프로그래밍하려니 힘들었는데 좋은 정보 감사합니다!
목록 삭게로! 맨위로
번호 제목 이름 날짜 조회
83220 [질문] 네비없이 지도만 가지고 여기저기 다닐수 있나요? [18] JazzPianist4351 16/05/18 4351
83218 [질문] 야구스탯 war 에 대해 알고 싶습니다. [2] 파란무테2042 16/05/18 2042
83217 [질문] 서울에 새벽에 축구경기 볼 수 있는 펍 같은 곳 있나요? [1] 삭제됨2617 16/05/18 2617
83216 [질문] 만약 새로운 닌자 챔피언이 나온다면 어떻게 될까요? [7] 니나노나2331 16/05/18 2331
83215 [질문] 인천공항 면세지역 식당 추천 부탁드립니다. [1] JIRO2389 16/05/18 2389
83214 [질문] 오사카/교토 지금 위험한가요? [9] 2847 16/05/18 2847
83213 [질문] 연봉을 측정할때 투수 war + 타자 war 더한것보다.. [10] 마르키아르2716 16/05/18 2716
83212 [질문] 티비를 사야하는데요!(10대) [2] 우왕1920 16/05/18 1920
83211 [질문] 유머글 찾습니다. Hazle1369 16/05/18 1369
83210 [질문] GTX 550 을 쓰고 있는데요...업그레이드 후 이녀석이 의미가 있을까요? [3] 이라세오날1771 16/05/18 1771
83209 [질문] 조깅 vs 전력질주 [10] 사장5538 16/05/18 5538
83208 [질문] 자막을 만들고 싶은데 쉽게 만들수있는 프로그램이 있나요? [2] 야야 투레2090 16/05/18 2090
83207 [질문] [스포주의] 곡성 보신 분들께 질문 좀 ... 저 망한 건가요? [22] 제랄드3329 16/05/18 3329
83206 [질문] '임을 위한 행진곡' 알고 있으세요?(부를 수 있나요?) [36] 리오넬 호날두3893 16/05/18 3893
83205 [질문] 도쿄입니다. 혼자갈만한 맛집 [7] 타마노코시3767 16/05/18 3767
83204 [질문] 다이어트 질문입니다. [7] 치느님1967 16/05/18 1967
83203 [질문] [LOL] 세계대회 그랜드슬램의 기준은 어떻게 정해야 할까요? [7] Vesta2599 16/05/18 2599
83202 [질문] 소개팅녀 생일 선물 질문 드려요 [24] Arya10558 16/05/18 10558
83201 [질문] 본인의 통합부채현황 관련 증명서를 발급받을수있나요?? [1] BBC특전대1711 16/05/18 1711
83200 [질문] 추첨함 구할때가 있을까요? [1] 싸구려신사1453 16/05/18 1453
83199 [질문] 자바스크립트+XMLHttpRequest 질문입니다. [6] 꼭두서니색1834 16/05/18 1834
83198 [질문] 삼성노트북 + 프로젝터 질문입니다. [3] vorhandensein1949 16/05/18 1949
83197 [질문] 여러가지 온라인알피지의 공성전 방식이 궁금합니다. [9] 스핔스핔1820 16/05/17 1820
목록 이전 다음
댓글

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