[JS] '비동기 프로그래밍'을 이용한 뉴스 워드클라우드 생성기 만들기

2021. 8. 24. 15:52IT/project

SMALL

제가 진행 중인 프로젝트는 검색창에 원하는 '키워드'를 입력하면

네이버의 뉴스 기사들의 제목을 크롤링 하여 워드클라우드를 생성해 주는 웹페이지입니다. ^~^ 😊😊

제가 재학 중인 '군산대'를 입력하니 '재정', '지원', '탈락', '이의신청' 등의 키워드들이 모여 워드 클라우드가 만들어졌네요. 여담으로 키워드를 통해 도출할 수 있는 인사이트를 잠깐 알려 드리자면 ... ! 🤔

 


군산대가 현재 일반재정지원대학미선정되어 내년부터 재정 지원이 중단될 것이라는 통보를 받았다는 것을 추측해볼 수 있습니다. 그래서 우리 학교 측에서는 이를 인정할 수 없어 이의신청을 제기하여 국민 청원에 올린 상태입니다.
많은 관심 부탁드립니다 ! 
https://www1.president.go.kr/petitions/Temp/hR6lu1  
 

대한민국 청와대

나라를 나라답게, 국민과 함께 갑니다

www.president.go.kr

 


 

아무튼 다시 프로젝트로 돌아와서, 저는 저 워드클라우드를 만들면서 팝업창에 생성한 워드 클라우드 이미지를 띄울 때 (뉴스 기사 크롤링 + 워드클라우드 생성) -> (이미지 보여주기) 

행위에 대해서 어떻게 해야할지 고민이 많았습니다.

이 이슈를 해결하기 위해선 '비동기 프로그래밍'의 개념이 필요하다는 것을 알았습니다.

 

 

1. 'setTimeout()' 을 이용한 비동기 프로그래밍

setTimeout()은 일정시간 후에 코드를 임의로 지연하여 실행하고 싶을 때 사용하는 함수입니다.

setTimeout(function () { // code here }, delay);

 

키워드를 입력하여 Enter를 쳤을 때 실행되는 함수입니다.

워드클라우드를 생성하고 $.post('/keyword', {name : text}); 

setTimeout을 사용하여 10초 (10000 msc) 후에 이미지를 팝업창에 로드하는 코드입니다. 

이때, src를 localhost:5000/static/파일명.확장자 로 접근하면 정적 파일로 접근할 수 있습니다.

function enterKey() { 
            if (window.event.keyCode == 13) { 
                var popup = new bootstrap.Modal(document.getElementById('popup'));
                text = $('.form-control').val()
                $('#popup #title').text(text)
                popup.show();
                path = 'static/' + text + '.png';
                // flask '/keyword' route 로 이동하여 WC 생성
                $.post('/keyword', {name : text});
                function showWC(path) {
                  console.log(path);
                  // img src 속성 변경
                  $('#wordcloud-img').attr("src", path);
                }
                
                // 비동기 프로그래밍 처리
                setTimeout(function() {showWC(path);}, 10000);

                spinner = $('.spinner-border')
                if ($('#wordcloud-img').css("display") == "none") {
                    spinner.show();
                }
                else {
                  spinner.hide();
                  }
            }
          }

HTML code

10 초후에 src 속성이 생겨 이미지가 로드될 수 있습니다.

<img id="wordcloud-img">

 

하지만 setTimeout()을 사용할 시, 임의로 delay(지연 시간)을 정해주어야 하여 키워드마다 각각 워드 클라우드 생성 시간이 다르기 때문에 꼬일 위험이 있습니다. 따라서 좋은 방법이 아니었습니다.

 

 

 

2. 'callback()' 을 이용한 비동기 프로그래밍

콜백 함수는 시간을 임의로 지정해 주는 것이 아닌, 특정 함수 실행을 끝낸 뒤 실행되는 함수를 말합니다. 

1. 워드클라우드 생성 -> 2. 이미지 보여주기 행위를 callback 하여 정의해 봅시다.

callback 함수 사용하여 비동기 처리를 하였습니다. 

               // 워드클라우드 생성
               function createWC(text, callback) {
                  console.log("!!!!!!!!!");
                  $.post('/keyword', {name : text});
                  path = 'static/' + text + '.png';
                  callback(path);
                }
                // 이미지 보여주기
                function showWC(path) {
                  console.log(path);
                  $('#wordcloud-img').attr("src", path);
                }
                
                createWC(text, showWC);

그런데 보시다시피 만약 '카카오' 키워드를 입력했을 때, createWC 함수가 먼저 실행되기는 하지만 (console 출력 참고) 

이미지가 생성이 완료되기도 전에 showWC(path) 함수를 실행해 경로를 참조하기 때문에 not found error가 납니다. 

뭐가 문제였던 걸까요?

문제점은 제가 callback을 createWC 함수와 showWC 함수와 연결시켜서, createWC 함수 안에 있는 $.post 자체에는 callback 이 안 먹었던 것이었습니다. 그래서 기다려 주지 않았어요 ㅠㅠ

해결책은 아래 코드와 같이 $.post ~ 에 callback을 먹이는 것입니다.

                spinner = $('.spinner-border')
                wordcloud = $('#wordcloud-img')
                
                function showWC(path) {
                  console.log(path);
                  $('#wordcloud-img').attr("src", path);
                }
 
                $.post('/keyword', {name : text}, function() {
                  spinner.hide();
                  wordcloud.show();
                  showWC(path);
                });

 

3. 'Promise' 개체 이용한 비동기 프로그래밍

Promise 개체는 비동기 작업의 완료 혹은 실패와 결과 값을 나타냅니다.

promise의 매개변수는 executor로, resolve( 이행) 와 reject(거부) 함수로 구성되어 있습니다. 

이 두 함수를 이용하여 비동기 작업이 모두 완료되면 resolve를 호출하여 이행하거나, 오류가 생기면 reject를 이용해 거부할 수 있습니다.

너무너무 설명이 잘 되어 있는 'promise',  저도 이 포스트를 많이 참고하였습니다.

https://joshua1988.github.io/web-development/javascript/promise-for-beginners/#promise%EA%B0%80-%EB%AD%94%EA%B0%80%EC%9A%94

 

자바스크립트 Promise 쉽게 이해하기

(중급) 자바스크립트 입문자를 위한 Promise 설명. 쉽게 알아보는 자바스크립트 Promise 개념, 사용법, 예제 코드. 예제로 알아보는 then(), catch() 활용법

joshua1988.github.io

                function getData() {
                  return new Promise(function(resolve, reject) {
                    let createWC = text => $.post('/keyword', {name : text});
                  resolve(createWC(text));
                  console.log('createWC 함수 실행');
                  });
                }
                
               getData().then(function(data) {
                  path = 'static/' + data
                  $('#wordcloud-img').attr("src", path);
                  console.log("!!")
                  console.log(path);
                });

 

getData() 함수를 통해 화살표 함수로 createWC 워드클라우드 생성 함수를 선언하였습니다.

createWC 함수가 성공적으로 완료되어 resolve 함수에게 결과값을 반환하면 그제서야 비동기적으로 절차에 맞게 이미지가 로딩되었습니다. 야호 !!!!! 👍👍👍👍👍👍

 

 

성공 !!!! 🤞🤞😁🤞🤞

'행복'을 입력하면 '선물', '행운', '복권', 당첨' 등이 나오네요..!!

역시 복권 당첨을 해야 행복이 오는 걸까요 ㅋㅋㅋㅋㅋ 모두 행복하세요 🤭🤭🤭💛

 

아무튼 잘못된 사항이 있거나 궁금한 점, 하고 싶은 말이 있으시다면 언제든지 말해 주세요!!

해당 프로젝트는 계속 업데이트 할 예정입니다. 

전체 코드는 깃허브에 공유하겠습니다 ㅎㅎ

 

읽어 주셔서 감사합니다~ 

 

 

 

 

LIST