selli
133
2021-01-14 11:15:00
6
235

자바스크립트 값 전역으로 사용하도록 하고 싶은데 안되요 ㅜㅜ


sbjCdTypeArr라는 배열을 ajax 바깥에서도 사용하고 싶은데.. success: function(response) {} 이 안에서는 값이 잘 나오고 바깥에서는 빈 배열이 나와요 ㅠㅠ 어떻게 하면 될까요??



function getColumnsByTabType(tabType) {

    let sbjCdTypeArr = [];  // 여기에 값이 담겨있어야 하는데 원래.. 
    
    $.ajax({
        type: 'GET',
        url: '/admin/api/metaTables/sbjCdTypes',
        dataType: 'json',
        cache: false,
        success: function (response) {
            //makeSbjCdTypeArr(response);
            sbjCdTypeArr = [];
            for (let i=0; i<response.length; i++) {
                let sbjTypeObj = {};
                sbjTypeObj['ID'] = response[i];
                sbjTypeObj['NAME'] = response[i];
                sbjCdTypeArr.push(sbjTypeObj);
            }
            console.log("--이건 나옴!!!!--");
            console.log(sbjCdTypeArr);
        },
        error: function (xhr, status, exception) {
            return false;
        }
    });
    console.log("--이건 안나옴!!!!! --");
    console.log(sbjCdTypeArr);  // [] 이렇게 빈값이 나옴
}


0
  • 답변 6

  • 퀘이사123
    552
    2021-01-14 11:21:43 작성 2021-01-14 11:25:08 수정됨

    ajax는 비동기통신입니다.

    아마 콘솔로그도 ajax안에 있는 로그보다 밖에 있는 로그가 먼저 찍혔을겁니다.


    보면 함수안에서 쓰고 싶으신거같은데

    어차피 서버에서 값을 받아온 후 처리를 하셔야 하니 success부분안에 처리할 코드를 넣으시면 될거같습니다.

  • hoonnote
    628
    2021-01-14 11:39:16

    ㅋㅋㅋ 비동기적으로 동작하는 코드여서 그래요

    function getColumnsByTabType(tabType) {
        let sbjCdTypeArr = [];  // 여기에 값을 담아봅시다
        
        $.ajax({
            type: 'GET',
            url: '/admin/api/metaTables/sbjCdTypes',
            dataType: 'json',
            cache: false,
    
    요까지 보면, ajax를 사용해서 url 주소에 GET 요청을 보내기로 했죠. 그러고 이 아래에 요청이 성공했을 시 
    어떤 동작을 하도록 할지 구현을 해주었어요
    
            이 부분은, GET 요청이 성공적으로 보내지고, 응답 결과를 받은 뒤에 실행이 되도록 기다리게 해줍니다
            한마디로 비동기적으로 받아오는 데이터를 완전히 다 받아온 다음에 실행이 되는거죠.
            success: function (response) {
                sbjCdTypeArr = [];
    
                받아온 데이터로 for loop을 돌면서 object값을 해당 array에 넣어주었죠. 
                for (let i=0; i<response.length; i++) {
                    let sbjTypeObj = {};
                    sbjTypeObj['ID'] = response[i];
                    sbjTypeObj['NAME'] = response[i];
                    sbjCdTypeArr.push(sbjTypeObj);
                }
    
                그리고 for loop이 다 돌아간 뒤에 console.log를 해보면 출력이 잘 됩니다
                console.log("--이건 나옴!!!!--");
                console.log(sbjCdTypeArr);
            },
            그리고 에러나면 false값을 리턴한대요.
            error: function (xhr, status, exception) {
                return false;
            }
        });
    
        근데 얘는 Ajax가 GET 요청을 보내자마자 console이 막 찍혀요. 
        AJax 비동기 데이터 요청 응답이 오지도 않았는데도 일단 콜스택에 쌓여있으니까 막 콘솔을 찍는겁니다. 
        따라서 데이터가 들어오지도 않았는데 출력을 해버리기때문에 [] 값이 나오는거에요 
        console.log("--이건 안나옴!!!!! --");
        console.log(sbjCdTypeArr);  // [] 이렇게 빈값이 나옴
    }
    
    이렇게 자바스크립트 공부 할때 많이 헷갈리는게 비동기적 처리인데요, 
    
    일단 컴퓨터는 사람이 형광등 스위치를 누르고, 불이 들어오는 그 짧은 찰나에 2개의 연산처리를 할 수 있을정도로 빠릅니다. 
    따라서 console.log() 같은 경우에도 엄청 빠른 속도로 처리가 되어 실행이 되죠. 
    
    그에비해, 비동기 통신 (ajax로 데이터 가져오는 동작)의 경우에는 우리가 체감하기에 엄청 빠른 속도로 데이터를 가져와도
    컴퓨터가 처리하는 속도에 비해 엄청 느려요. 
    
    그렇기 때문에 질문자님께서 물어본것처럼 !!!일부로!!! 데이터 통신 값을 전달받기 전까지 코드실행을 대기시키지 않는 한
    (success: function() 이부분처럼요), 자바스크립트는 그냥 코드 쌓여있는걸 순차대로 실행을 합니다
    
    그래서 이런 통신 데이터를 활용하는 경우에는 비동기 처리를 잘 해주어야 원하는 결과값을 받아올 수 있어요,
  • 피자7
    637
    2021-01-14 13:26:18 작성 2021-01-14 13:34:06 수정됨

    js에서 전역변수 쓰면 안됨

    글고 추가로 답변 드리자면

    윗댓분들이 비동기에대해 간략적으로 설명했는데

    비동기가 뭔지 자세히 모르면 반드시 비동기 동작 개념,콜백, 더 나가서

    프로미스가 뭔지 한번 공부하세여 이해가 될때까지 계속 봐야함

  • CUA
    26
    2021-01-14 13:52:42 작성 2021-01-14 13:54:55 수정됨

    @피자7

    js에서 전역변수를 사용하면 안되는 이유를 여쭤봐도 될까요?

  • hoonnote
    628
    2021-01-14 15:24:19

    전역변수는 대체적으로 피하는게 좋긴 해요.

    자바스크립트에서 함수를 실행시키는 경우에, 해당 함수 안에서 사용할 수 있는 블록인 컨텍스트라는 친구가 생성이 됩니다. 그리고, 해당 컨텍스트에는 함수 안에서 선언한 변수들 값이 생성되어 사용할 수 있고, 함수 밖에서는 해당 변수를 사용할 수가 없지요.



    const myContext = () => {
      const myVar = "is it accessible?"

      console.log(myVar// is it accessible
    }

    myContext()
    console.log(myVar//undefined



    따라서 자바스크립트에서는 해당 컨텍스트 안에 변수명이 존재하지 않는다면, 컨텍스트 외부로 나가서 global context 안에 해당되는 변수가 있는지를 체크합니다


    let myVar;
    const myContext = () => {
      myVar = "is it accessible?"

      console.log(myVar// is it accessible
    }

    myContext()
    console.log(myVar//is it accessible


    그래서 전역변수를 사용하여 어디서든지 사용할 수 있는 변수를 만들자 라는 생각에 전역변수를 쓸수도 있는데요, 그렇게되면 발생하는 문제가 대표적으로 다른 함수들에서도 해당 변수값을 참조 및 변경을 하게 되어서, 우리가 원치 않는 에러를 발생 시킬 수 있습니다.



    let name;

    function myName() {
      name = "hoon"
      console.log(name)
    }

    function employee() {
      name = "John";
      role = "marketer";
    }

    myName()  // name 값을 hoon으로 지정
    employee() // 여기서 name 값이 john으로 변경

    console.log(name)  // hoon 이름을 사용하고 싶어 name을 사용했지만, employee()  함수에서 전역 변수를 바꾸어 우리가 원하는 값을 받지 못함



  • CUA
    26
    2021-01-21 13:17:21

    @hoonnote 오랜만에 들어와서 이제야 확인했네요. 상세한 답변 감사합니다 :)

  • 로그인을 하시면 답변을 등록할 수 있습니다.