IE11 에서 es6와 Promise까지 지원하고 싶다.

 

webpack 쓰면 되는거 알겠는데 그냥 간단히 빨리 지원하고싶다.

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <title>Title</title>
</head>
<body>

</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.12.1/polyfill.js"></script>

<script type="text/babel">
  alert(`dd`);

  function resolveAfter2Seconds() {
    return new Promise(resolve => {
      setTimeout(() => {
        resolve('resolved');
      }, 1000);
    });
  }

  async function asyncCall() {
    console.log('calling');
    const result = await resolveAfter2Seconds();
    alert(result);
  }

  asyncCall();
</script>
</html>

1. html 파일에 babel, polyfill cdn을 넣는다.

2. es6 문법과 Promise 지원 확인한다.

 

IE11 쓰면 벌금 메겼으면 좋겠다.

 

'JS' 카테고리의 다른 글

javascript 비동기 재귀 함수  (0) 2020.09.28
Promise 자바스크립트(js)  (0) 2019.10.18
loading button 쉽게 만들기(with js)  (0) 2019.10.15
js 화살표함수(arrow function)  (0) 2019.10.14
JS prototype(프로토타입)  (0) 2019.09.25
재귀 함수 + 비동기
  const onSubmit = async () => {
    let response = await create_customer();
    if (response.status !== 200) {
      return onComplete(false, '수집 되지 않은 좌표가 있습니다');
    }

    const invalidMutualDistanceCustomers = response.data;
    response = await getMutualDistanceByTmapRecursive(invalidMutualDistanceCustomers);

    try {
      response = await create_route();
    } catch (error) {
      return onComplete(false, '경로 생성 실패');
    }

    return onComplete(true, '배차 완료');
  };

 

위의 코드는 submit 버튼을 누르면 동작하는 async 함수다.

 

고객을 생성하고 유효하지 않은 고객들(invalidMutualDistanceCustomers 배열)을 재귀 + 비동기 함수로 처리 하려한다.

 

setTimeout 대신 사용할 비동기 sleep 함수
const timeout = ms => new Promise(resolve => setTimeout(resolve, ms));

 

재귀 함수
  const getMutualDistanceByTmapRecursive = async (invalidMutualDistanceCustomers: Array) => {

    const customer: Array = invalidMutualDistanceCustomers.pop();

    if (customer === undefined) {
      return;
    }

    await timeout(800);

    const response = await getMutualDistanceByTmap(customer[0], customer[1]);
    const totalDistance = response.data.features[0].properties.totalDistance;
    const jsonMap = JSON.stringify(response.data);
    await save(customer[0], customer[1], totalDistance, jsonMap);
    await getMutualDistanceByTmapRecursive(invalidMutualDistanceCustomers);

  }

 

1. 배열을 하나씩 pop 해주고 배열이 하나도 없으면(customer === undefined) 재귀 함수 종료

2. await timeout(800) : 0.8초 뒤에 api를 호출해라(api 초당 제한)

3. tmap api 호출하고 저장한 다음 다시 재귀 함수(getMutualDistanceByTmapRecursive) 호출

 

 

결론 : 비동기 처리는 까다로우니 async, await를 많이 박자

'JS' 카테고리의 다른 글

javascript es6 + Promise IE11 간단히 지원  (1) 2021.06.11
Promise 자바스크립트(js)  (0) 2019.10.18
loading button 쉽게 만들기(with js)  (0) 2019.10.15
js 화살표함수(arrow function)  (0) 2019.10.14
JS prototype(프로토타입)  (0) 2019.09.25

비동기 Call하면 "그냥 Jquery의 ajax로 다 바르면 되잖아! 근데 자꾸 무슨 Promise냐..." 이렇게 생각하곤했다.

하지만 기술의 발전을 따라 가지 못하면 도태됨으로 Promise를 배웠다.(빠른건 아니지만..) 적용해보니 확실히 코드도 깔끔해지고 좋은것 같다. javascript의 싱글스레드를 좀 더 이해 하는 느낌도 들면서, 고수가 된 느낌도 들면서

 

 

정의 : Promise 개체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다. 

 

내 생각: 비동기 Call을 날리고 성공(resolve)과 실패(reject)를 내가 깔끔하게 처리해줄게(Callback 쓰지마세요) 왜냐? 코드가 더러워지니깐 이게 다 깔끔하려고 하는거다

 

코드를보자

 

1. 첫번째 간단한 Promise 예제

// 정의
let p = new Promise((resolve, reject) => {
    let a = 1 + 1;

    if (a === 2) {
        resolve('Success')
    } else {
        reject('False')
    }
});

// 실행
p.then((data => {
    console.log('resolve' + data) // 성공 시 Success
})).catch((data => {
    console.log('reject' + data) // 실패 시 False
}));

간단하게 말해서 Call 날린뒤 성공은 then의 함수가 실패하면 catch의 함수가 실행된다.(이때 함수는 Arrow function을 사용했다) a는 2니깐 당연히 then 함수의 Success가 실행됨!

 

 

2-1. 두번째 Promise 적용 전

const bossLeft = true;
const workLeft = false;

function goToHome(callback, errorCallback) {
    if (bossLeft) {
        errorCallback('아 집에좀 가세요')
    } else if(workLeft) {
        errorCallback('아 일좀 줄여주세요 진짜')
    } else {
        callback('상사도 없고 일도 없으니 집간다')
    }
}


goToHome((message) => {
    console.log(message)
}, (message) => {
    console.log(message)
});

goToHome 집에 가는 함수다. 파라미터로 callback과 errorCallback을 받아서 상사가 남아있냐, 일이 남아있냐에 따라서 실행될 함수가 결정된다.

 

 

2-2. 두번째 Promise 적용 후

const bossLeft = false;
const workLeft = false;

function goToHome() {
    return new Promise((resolve, reject) =>{
        if (bossLeft) {
            reject('아 집에좀 가세요')
        } else if(workLeft) {
            reject('아 일좀 줄여주세요 진짜')
        } else {
            resolve('상사도 없고 일도 없으니 집간다')
        }
    });
}


goToHome().then((message)=>{
    console.log(message);
}).then(()=>{ // 이런식으로 then을 더붙이면 then 실행 후 그 다음 또 실행함
    console.log('그다음 콜백?');
}).catch((message)=>{
    console.log(message)
});

이렇게 코드가 깔끔해진다! goToHome은 파라미터를 받을 필요도 없어지고 new Promise의 reslove, reject로 결정하면된다. 추가로 resolve 호출은 then, 실패는 catch다. 더 추가로 then뒤에 다시 then을 붙이면 또 실행된다. 꿀이다.

 

 

3. 세번째 Promise all

let firstPromise = new Promise((resolve, reject)=>{
    resolve('first complete')
});

let secondPromise = new Promise((resolve, reject)=>{
    resolve('second complete')
});

let thirdPromise = new Promise((resolve, reject)=>{
    resolve('third complete')
});

Promise.all([firstPromise, secondPromise, thirdPromise]).then((message)=>{
    console.log(message)
});

3개의 Promise 모두 비동기 Call이 모두 끝났을때 then의 함수를 실행시킨다. 이거 진짜 물건이다. 비동기 Call을 하나로 묶어주는 역할!

 

 

4. 네번째 Ajax와 Promise의 만남

    getOnetoFiveRanking = () => {
		return new Promise((resolve, reject)=>{
			$.ajax({
				url: this.url1,
				crossDomain: true,
				data:JSON.stringify(this.form.serialize()),
				dataType: 'json',
				contentType: "application/json",
				headers:{"x-api-key": "비밀"},
				type: 'POST',
			}).done((data)=>{
				resolve(data); // done 시 resolve
			}).fail(function (xhr, textStatus) {
				reject(xhr, textStatus); // ,fail 시 reject
			});
		})
	};
    
    
    this.getOnetoFiveRanking().then((data)=>{
        console.log(data);
    }).catch((xhr, textStatus)=>{
        console.log(xhr, textStatus);
    });
    
    
    

$.ajax의 done일때 resolve, fail일때 reject! 심플하고 좋다.

 

5. 다섯번째 Ajax와 Promise.all()의 만남

    getOnetoFiveRanking = () => {
		return new Promise((resolve, reject)=>{
			$.ajax({
				url: this.url1,
				crossDomain: true,
				data:JSON.stringify(this.form.serialize()),
				dataType: 'json',
				contentType: "application/json",
				headers:{"x-api-key": "비밀"},
				type: 'POST',
			}).done((data)=>{
				resolve(data);
			}).fail(function (xhr, textStatus) {
				reject(xhr, textStatus);
			});
		})
	};


    getSixtoTenRanking = () => {
		return new Promise((resolve, reject)=>{
			$.ajax({
				url: this.url2,
				crossDomain: true,
				data:JSON.stringify(this.form.serialize()),
				dataType: 'json',
				contentType: "application/json",
				headers:{"x-api-key": "비밀2"},
				type: 'POST',
			}).done((data)=>{
				resolve(data);
			}).fail(function (xhr, textStatus) {
				reject(xhr, textStatus);
			});
		})
	};
    
    // getOnetoFiveRanking와 getSixtoTenRanking 비동기 Call이 둘다 끝나면 then 실행!
    Promise.all([this.getOnetoFiveRanking(), this.getSixtoTenRanking()]).then((message)=>{
        console.log(message);
    });

여기서 주의할 점은 메소드를 실행하듯()을 붙여야 한다는것! 그러면 두 메소드가 다 실행되면 그때 then을 수행한다! 이건 정말 실전에서 많이 쓰이니깐 유용함

 

결론 : callback을 깔끔하게 쓰기위해 Promise를 쓰자

'JS' 카테고리의 다른 글

javascript es6 + Promise IE11 간단히 지원  (1) 2021.06.11
javascript 비동기 재귀 함수  (0) 2020.09.28
loading button 쉽게 만들기(with js)  (0) 2019.10.15
js 화살표함수(arrow function)  (0) 2019.10.14
JS prototype(프로토타입)  (0) 2019.09.25

사용자의 Re-Click을 방지하기 위해서 "클릭 했으니깐 기다려주세요!" 라는 메세지를 전달하기 위해서는 loading button이 짱이다.

 

간단하게 loading button을 만드는 css를 적어보자 한다.

 

참조 사이트 : https://loading.io/button/

 

Loading Buttons / Pure CSS Button that Loads

Loading Button with CSS animation for better loading experience with Bootstrap, PureCSS and other frameworks.

loading.io

 

1. loading.css와 loading-btn.css를 다운한다.

2. 버튼을 만든다(클릭 시 버튼 옆에 loading 이미지 생성)

<button id="search">검색
	<span class="ld ld-ring ld-spin-fast"></span>
</button>

3. 버튼 옆에 loading 버튼이 돌아가는것을 확인 후 jquery로 토글한다

class Main {
    constructor() {
        this.setSubmitEvent();
        this.loadingButton = '<span class="ld ld-ring ld-spin-fast"></span>'; // loading 버튼
        this.button = $('#search');
    }

    setButtonDisable = () => {
    	this.button.append(this.loadingButton); // loading 버튼 확성화
    	this.button.attr('disabled', true); // 재 클릭 방지를 위한 button disable
	};

    setButtonEnable= () => {
		$('#search span').remove();
    	this.button.attr('disabled', false);
	};

    setSubmitEvent(){
		$("#search-form").submit((e) => {
			e.preventDefault();

			let form = $("#search-form");

			$.ajax({
				url: '/',
				data: form.serialize(),
				type: 'post',
				dataType: 'json',
				beforeSend: ()=> {
					this.setButtonDisable();
				},
			}).done((data)=>{
				this.setButtonEnable();
				$("#result-table tbody").html(data.html_ranking_list);
			}).fail(function (xhr, textStatus) {
				alert('실패');
			});

			return false;

		});
    }

}

 

결론 : loading 버튼은 필요하지만 매번 만들기 귀찮다 복붙을 잘하자.

'JS' 카테고리의 다른 글

javascript es6 + Promise IE11 간단히 지원  (1) 2021.06.11
javascript 비동기 재귀 함수  (0) 2020.09.28
Promise 자바스크립트(js)  (0) 2019.10.18
js 화살표함수(arrow function)  (0) 2019.10.14
JS prototype(프로토타입)  (0) 2019.09.25


헷갈리는 화살표함수를 정리해보자 한다.

1. 왜생겼을까?
 - 함수를 좀 간결하게 쓰려고(한줄로)
 - javascript OOP 형태로 Class에 넣어서 코딩할때 this의 바인딩 문제를 해결하기 위해


2. 함수를 한줄로의 관점에서


function sum(a, b) { // 익숙한 표준 함수 : 길다 길어..
    return a+ b
}

let arrowSum = (a, b) => { // function 대신에 ()가 들어가서 좀 짧긴하지만 그래도...
    return a + b
};

let oneLineArrowSum = (a, b) => a + b; // { return expression } 을 a + b로 표현했다(간결하다)

function isPositive(number) { // 익숙한 표준 함수 2
    return number >= 0
}

let arrowIsPositive = (number) => number >= 0; // number >= 0 으로 간결하게 표현

let arrowIsPositive2 = number => number >= 0; // 파라미터가 하나 일때는 괄호를 제외할 수 있다

function randomNumber() { // 익숙한 표준 함수 3
    return Math.random()
}

let randomNumber2 = () => Math.random(); // 파라미터가 없을 경우 ()로 시작

document.addEventListener('click', function () { // 익숙한 표준 함수 4
    console.log('Click')
});

document.addEventListener('click', ()=> console.log('Click')); // 한줄로 깔끔하게!

3. this 바인딩 문제의 관점에서


class Person {
    constructor(name) {
        this.name = name
    }

    arrowPrintName() {
        setTimeout(() => {
            console.log(this);
            console.log('Arrow ' + this.name)
        }, 100)
    }

    normalPrintName() {
        setTimeout(function () {
            console.log(this);
            console.log('Function: ' + this.name)
        }, 100)
    }
}

person = new Person('이승우');
person.arrowPrintName() // Person의 this.name이 정상적으로 출력 + this는 Person을 가르킴
person.normalPrintName() // this는 엉뚱한 windows 전역변수를 가르킴(this.name은 당연히 출력 안됨)

 

4. 결론

 - 잘 만쓰면 코드도 깔끔해지고 특히 js에서 OOP로 코딩할때는 필수!

'JS' 카테고리의 다른 글

javascript es6 + Promise IE11 간단히 지원  (1) 2021.06.11
javascript 비동기 재귀 함수  (0) 2020.09.28
Promise 자바스크립트(js)  (0) 2019.10.18
loading button 쉽게 만들기(with js)  (0) 2019.10.15
JS prototype(프로토타입)  (0) 2019.09.25

JS를 쓰면서 항상 헷갈렸던게 프로토타입이다. Class도 없고 Function을 Class처럼 쓰고.. 물론 새로나온 JS는 아니지만 어쨋든 헷갈리면서도 일하는데 불편함이 없어서 그냥 넘어가던걸 한번 정리하고자 한다. 참조한 문서는https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes이다.

 

JS는 prototype-based라고 한다. prototype은 필요한 메소드, 프로퍼티를 정의해놓고 그것을 상속해주기위한 도구라고 생각한다. 이것을 여러단계로 상속하면 prototype chain이라고 부르는 것 같다. 예제를 보자

 

function Person(name) {
  this.name = name;
  this.greeting = function() {
    alert('Hi! I\'m ' + this.name + '.');
  };
}

 

const person1 = new Person('승우') // function으로 Class를 만들었던 JS는 참 비극이다.

 

이렇게 Object를 만들면 person1이 사용할 수 있는 메소드와 프로퍼티는 name과 greeting이여야 하는데 

person1.valueOf()을하면 먹힌다. Person에는 valueOf이라는게 없는데. 그렇데 프로토타입으로 부터 상속 받은것이다.

 

 

JS의 모든것은 Object이다. function, String, Number등등 그냥 다 Object이다. 그래서 Person function 또한 Object로 부터 상속받는다. 이러한 이유로 person1.valueOf()이 먹힌다는 말씀이시다.

조금만 더 정확히 기술하자면 Object.prototype 의 Object에 기술되어 있다. Object에 관한 문서를 보면 상당히 많은 메소드와 프로퍼티가 있지만 모두다 상속 되지 않는다. Object.prototype에 기술된 것들만 상속된다.

 

이부분을 약간만 응용하자만

 

const myString = 'This is my string.'; // String prototype으로 부터 split(), replace()와 같은 아름다운 메소드들을 상속 받기 때문에 myString.split()을 사용할 수 있다는 말이다.

 

조금 더 응용하자면 Date의 커스텀 prototype을 만들어서 내가 원하는 메소드를 구현하고자 한다.

 

Date.prototype.yyyymmdd = function () {
   var mm = this.getMonth() + 1;
   var dd = this.getDate();
   return [this.getFullYear(), (mm > 9 ? '' : '0') + mm, (dd > 9 ? '' : '0') + dd].join('-');
}; // yyyymmdd 메소드를 프로토타입에 정의한다.

 

var date = new Date();

var plusThreeDate = new Date(date.getTime() + (3 * 24 * 60 * 60 * 1000)); // 3일 뒤 Date 생성

plusThreeDate.yyyymmdd() // "2019-09-28"과 같이 yyyymmdd 메소드를 사용할 수 있다.

 

 

 

 

'JS' 카테고리의 다른 글

javascript es6 + Promise IE11 간단히 지원  (1) 2021.06.11
javascript 비동기 재귀 함수  (0) 2020.09.28
Promise 자바스크립트(js)  (0) 2019.10.18
loading button 쉽게 만들기(with js)  (0) 2019.10.15
js 화살표함수(arrow function)  (0) 2019.10.14

+ Recent posts