**모듈과 같이 오늘 내용도 중요**
동기 비동기에 대하여..
https://jwinjection.tistory.com/62
동기, 비동기(콜백함수)
자바스크립트는 기본적으로 동기실행방식이다 a->b->c (a가 다끝나야지만 b가 실행되고 그다음 c실행) =>이게 동기식 하지만 setTimeOut과 같은 콜백함수를 쓰게 되면 비동기식으로 처리를 하게되고 a
jwinjection.tistory.com
✅ promise
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise
비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다
- 프로미스 자바스크립트 비동기 처리에 사용되는 객체
- 주로 서버에서 받아온 데이터를 화면에 표시할 때 사용
- 프로미스 객체가 만들어지게 되고 서버로 비동기 처리를 함(익명함수에 의해)
- 프로미스 리턴받은 객체
- then(정상적으로 프로미스 객체가 리턴되었다면 필요한 일을 수행)
- catch(에러객체가 리턴되었다면 에러를 처리)
- finally(최종적으로 처리할 일을 수행, 에러가 났든 안났든 무조건 실행)
ex.Day7 비동기 예제를 프로미스로 바꾸기
promise예제1
function runInDelay(seconds){
return new Promise((resolve,reject)=>{
//new 가 들어가면 성공 혹은 실패를 지정가능하고 첫번째 인자가 성공자리
if(!seconds || seconds < 0){
reject(new Error('seconds가 0보다 작음!'));
//reject은 무조건 catch로 이동 실행시 아래 settimeout은 실행안됨
}
setTimeout(resolve,seconds * 2000);//=>2초후 resolve실행
//setTimeout은 함수-> resolve랑 reject는 함수이다.
//resolve랑 reject의 ()괄호안에는 리턴해줄 값만 넣어주면된다
})
}
// runInDelay(2)
// .then(() => console.log('타이머가 완료되었습니다!')) //resolve(성공시)
// .catch(console.error) //reject(실패시)
// .finally(()=>console.log('모든작업이 끝났습니다'))
runInDelay()
.then(() => console.log('타이머가 완료되었습니다!')) //resolve(성공시)
.catch(console.error) //reject(실패시)
.finally(()=>console.log('모든작업이 끝났습니다'))
--결과--
Error: seconds가 0보다 작음!
at /Users/jaewon/Desktop/onedrive/study/javascript/Day8/1_promise1.js:5:20
at new Promise (<anonymous>)
at runInDelay (/Users/jaewon/Desktop/onedrive/study/javascript/Day8/1_promise1.js:2:12)
at Object.<anonymous> (/Users/jaewon/Desktop/onedrive/study/javascript/Day8/1_promise1.js:17:1)
at Module._compile (node:internal/modules/cjs/loader:1159:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
at Module.load (node:internal/modules/cjs/loader:1037:32)
at Module._load (node:internal/modules/cjs/loader:878:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:23:47
모든작업이 끝났습니다
promise예제2
function fetchEgg(chicken){
return Promise.resolve(`${chicken} => 🥚`);
//new가 없을때는 resolve 혹은 reject 하나만 바로 사용해야함!
//return Promise.resolve()는 무조건 성공이라
//안에있는 `${chicken} => 🥚` 얘를 fetchegg 호출한곳에 있는 .then에 넘겨줌
}
function fryEgg(egg){
return Promise.resolve(`${egg}=> 🍳`);
}
function getChicken(){
// return Promise.resolve(`🐔 => 🐓`);
return Promise.reject(new Error('치킨이 다 떨어졌음!'))
}
// getChicken()
// .then((chicken)=>{ //리턴까지 성실하게 쓰고싶을때
// return fetchEgg(chicken)
// })
// .then((egg) => fryEgg(egg)) //한줄일땐 자동 리턴이라 리턴,중괄호 생략가능!
// .then((friedEgg) => console.log(friedEgg))
// .catch((error) => console.log(error.name));
//일반형(일반형을 먼저 이해해야 축양형이해가능)
getChicken() //캐치에 매개변수로 new Error('치킨이 다 떨어졌음!') 얘가 전달
.catch(() => '🐥') //하지만 매개변수가 없어서 저내용을 안받음
//그래서 병아리만 아래 chicken으로 전달
.then((chicken)=>{
return fetchEgg(chicken)
})
.then((egg) => fryEgg(egg)) //한줄일땐 자동 리턴이라 중괄호생략함
.then((friedEgg) => console.log(friedEgg))
// 축약형
getChicken()
.catch(() => '🐥')
.then(fetchEgg)
.then(fryEgg)
.then(console.log);
--결과--
🐥 => 🥚=> 🍳
promise예제3
function getBanana(){
return new Promise((resolve) =>{
setTimeout(() => {
resolve('🍌');
},1000);
});
}
function getApple(){
return new Promise((resolve) =>{
setTimeout(() => {
resolve('🍎');
},3000);
});
}
function getOrange(){
return new Promise((resolve,reject)=>{
setTimeout(reject(new Error('no orange!')),2000)
})
}
// Bring apple and banana at the same time!
// Save banana and apple in array and print it on console.
// 순차적으로 처리 -> 총 4초가 걸림
getBanana()
.then((banana)=>getApple()
.then((apple) =>[banana,apple]))
.then(console.log)
// Promise.all : 병렬적으로 한번에 모든 Promise들을 실행
Promise.all([getBanana(), getApple()]) //1초,3초 -> 3초
.then((fruits) => console.log('✓ Promise.all: ',fruits))
// Promise.race: 주어진 Promise중에 가장 빨리 수행된 것이 출력
Promise.race([getBanana(),getApple()]) //1초,3초 -> 1초
.then((fruit)=> console.log('✓ Promise.race: ', fruit))
//promise.all에 reject가 포함시
//심지어 reject도 2초후실행하게끔 설정했는데
//앞에 then 다무시하고 바로 catch로 이동
Promise.all([getBanana(),getApple(),getOrange()])
.then((fruits) => console.log(`✓ Error: `, fruits))
.catch(console.log)
//allSettled는 그냥 매개변수에 적은 순서대로 잘실행되었는지,reject되었는지 확인하는용도
//실행은 병렬실행이라 제일 시간늦은 요소를 기준으로 최종출력
//출력순서는 매개변수에 적힌 순서대로
Promise.allSettled([getBanana(),getApple(),getOrange()])
.then((fruits) => console.log('✓ Promise.allSettle: ',fruits))
.catch(console.log)
--결과--
Error: no orange!
at getOrange (/Users/jaewon/Desktop/onedrive/study/javascript/Day8/3_promise3.js:18:27)
at Object.<anonymous> (/Users/jaewon/Desktop/onedrive/study/javascript/Day8/3_promise3.js:38:37)
at Module._compile (node:internal/modules/cjs/loader:1159:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
at Module.load (node:internal/modules/cjs/loader:1037:32)
at Module._load (node:internal/modules/cjs/loader:878:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:23:47
✓ Promise.race: 🍌
✓ Promise.all: [ '🍌', '🍎' ]
✓ Promise.allSettle: [
{ status: 'fulfilled', value: '🍌' },
{ status: 'fulfilled', value: '🍎' },
{
status: 'rejected',
reason: Error: no orange!
at getOrange (/Users/jaewon/Desktop/onedrive/study/javascript/Day8/3_promise3.js:18:27)
at Object.<anonymous> (/Users/jaewon/Desktop/onedrive/study/javascript/Day8/3_promise3.js:42:44)
at Module._compile (node:internal/modules/cjs/loader:1159:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
at Module.load (node:internal/modules/cjs/loader:1037:32)
at Module._load (node:internal/modules/cjs/loader:878:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:23:47
}
]
[ '🍌', '🍎' ]
✅async/await
- promise를 사용하고 있는 비동기 함수를 동기 함수처럼 사용할 수 있게 해주는 도구인 async와 await
- callback, Promise 비동기처리를 좀더 쉽게 처리할 수 있도록 사용됨
- ES7(2017)에 추가된 문법
1. 함수앞에 async를 붙여줌
async function 함수명(){
...
}
2. 결과를 리턴받는 함수앞에 await를 붙여줌
async function 함수명(){
변수명 = await 함수명();
...
}
async예제1
function getBanana(){
return new Promise((resolve) =>{
setTimeout(() => {
resolve('🍌');
},1000);
});
}
function getApple(){
return new Promise((resolve) =>{
setTimeout(() => {
resolve('🍎');
},3000);
});
}
function getOrange(){
return Promise.reject(new Error('no orange!'));
}
// 바나나와 사과를 같이 가지고 오기
async function fetchFruits(){
const banana = await getBanana(); //1초 얘가 끝나야 아래줄실행!!
//여기선 .then(banana)안써도 리턴값이 반환된다!
const apple = await getApple(); //3초
return [banana, apple] //최종 4초후에
}
fetchFruits()
.then((fruits) => console.log(fruits))
--결과--
[ '🍌', '🍎' ]
async예제2
function fetchEgg(chicken){
return Promise.resolve(`${chicken} => 🥚`);
}
function fryEgg(egg){
return Promise.resolve(`${egg}=> 🍳`);
}
function getChicken(){
// return Promise.resolve(`🐔 => 🐓`);
return Promise.reject(new Error('치킨이 다 떨어졌음!'))
}
async function makeFriedEgg(){
let chicken;
try{
chicken = await getChicken()
}catch{
chicken = '🐥';
}
const egg = await fetchEgg(chicken);
return fryEgg(egg);
}
makeFriedEgg().then(console.log);
--결과--
🐥 => 🥚=> 🍳
✅JSON(JavaScript Object Notation)
- 데이터를 저장하거나 전송할 때 사용되는 경량의 DATA 교환 형식
- 사람과 기계 모두 이해하기 쉬우며 용량이 작아서 XML을 대체하여 데이터 전송등에 많이 사용
- 데이터 포멧일 뿐, 통신 방법도 프로그래밍 문법도 아님
JSON의 특징
- 서버와 클라이언트간의 교류에서 일반적으로 많이 사용
- 자바스크립트를 이용하여 JSON 형식의 문서를 자바스크립트 객체로 변환하기 쉬움
- 자바스크립트 문법과 굉장히 유사하지만 텍스트 형식일 뿐임
- 특정 언어에 종속되지 않으며 대부분 프로그래밍 언어에서 JSON 포멧의 데이터를 핸들링 할 수 있는 라이브러리를 제공
{
"name":"루시",
"aga":13,
"family":"포메",
"weight":3.5
}
✅ JSON은 이름과 값으로 구성된 프로퍼티의 정렬되지 않은 집합, 자바스크립트 객체와 다른점은 메소드 프로퍼티가 없음
JSON의 구조
- 이름과 값의 쌍으로 이루어짐
- 데이터는 쉼표로 구분하여 나열
- {}중괄호로 둘러싸져 표현
- 배열은 []대괄호로 둘러싸여 표현
JSON의 타입
- 숫자(number)
- 문자열(string)
- 불리언(boolena)
- 객체(object)
- 배열(array)
- null
만약 배열을 쓰고싶다?
{
"dog":[
{"name":"루시","aga":13,"family":"포메","weight":3.5},
{"name":"뽀비","aga":10,"family":"사모예드","weight":10.5},
{"name":"토니","aga":7,"family":"포메","weight":2.5}
]
}
json 예제1
const dog = {
name: 'lucy',
age: 13,
eat: () => {
console.log('i am eating!')
}
};
const json = JSON.stringify(dog);
console.log(json); //메소드만 빠져있음
console.log(dog); //그렇다고 진짜로 객체에 메소드가 사라진건아님
const obj = JSON.parse(json);//문자열 데이터를 자바스크립트 객체로 변환(역직렬화,Deserializing)
console.log(obj);
--결과--
{"name":"lucy","age":13}
{ name: 'lucy', age: 13, eat: [Function: eat] }
{ name: 'lucy', age: 13 }
*fetch?
- fetch함수를 사용하면 리소스를 비동기로 요청할 수 있습니다.
- fetch를 호출하면 브라우저는 요청을 보내고 Promise 객체를 반환합니다. 요청이 완료되면 성공 여부에 상관없이 Promise가 resolved 되어 Response 객체가 반환됩니다. (404, 500 같은 경우와 같은 응답 코드를 받은 경우는 에러를 일으키지 않습니다.)
- HTTP 요청이 완료되지 못한 상태라면 Promise가 rejected 됩니다. 이 경우 catch 메서드를 사용하여 에러를 처리할 수 있습니다. (네트워크 문제 및 존재하지 않는 사이트에 대한 요청에 해당합니다.)
- Response 객체는 응답에 대한 정보를 담고 있습니다. ok, status 속성을 이용하여 응답 성공 여부를 확인할 수 있습니다.
json예제2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
function fetchAPI(){
return fetch('https://www.7timer.info/bin/astro.php?lon=113.2&lat=23.1&ac=0&unit=metric&output=json&tzshift=0')
.then((response) => response.json())
.then((data)=>data);
}
fetchAPI().then((datas) =>{
console.log(datas.dataseries);
showDatas(datas.dataseries);
});
function showDatas(datas){
const ulElement = document.querySelector('#dataseries');
ulElement.innerHTML = datloas.map((data) => setLiElement(data)).join('');
}
function setLiElement(data){
return `<li>cloudcover:${data.cloudcover} lifted_index:${data.lifted_index} prec_type:${data.prec_type} rh2m:${data.rh2m} seeing:${data.seeing} temp2m:${data.temp2m} timepoint:${data.timepoint} transparency:${data.transparency}</li>`;
}
</script>
<!-- <script>
fetch('https://www.7timer.info/bin/astro.php?lon=113.2&lat=23.1&ac=0&unit=metric&output=json&tzshift=0') //브라우저 api라 노드로 실행안됨, 비동기 통신 함수,
.then((response) => {
return response.json();
})
.then((data) => {
for(let i of data.dataseries){
const json = JSON.stringify(i);
document.getElementById('hh').innerHTML+=json,'<br>';
}
})
// .then((data) => console.log(data.dataseries[0]))
</script> -->
<title>json</title>
</head>
<body>
<h2 id='hh'>json</h2>
<ul id='dataseries'>
<li></li>
</ul>
</body>
</html>
콘솔창에 불러와짐
json 문법오류 체크사이트
https://jsonlint.com/
stringify(object): JSON
객체를 문자열로 변환(직렬화, Serializing)
parse(JSON): object
문자열 데이터를 자바스크립트 객체로 변환(역직렬화,Deserializing)
과제
인터넷에서 JSON API를 자유롭게 검색하고 해당 API를 호출하여 페이지에 출력하는 예제를 만들어보자
- get방식
- post방식
- 깃허브에 새로운 repository를 만들고 readme.md 생성,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
const your_projectKey = 'ctbtr6j62663_j2_eb6p7r99_jjjepbj';
params='data';
let url = `https://open.jejudatahub.net/api/proxy/aa7t3a3tabDtbD38a87ta8ttttt388ab/${your_projectKey}?${params}`
let testyear =0;
function fetchAPI(){
return fetch(url) //
.then((response) => response.json())
//안에는 json 형식이긴하나 fetch를통해 문자열로 그대로 받아오기때문에 json형태로파싱
.then((data)=>data) // return data
.then((datas) =>{
console.log(datas.data);
showDatas(datas.data);
});
}
fetchAPI();
function showDatas(datas){
const ulElement = document.querySelector('#dataseries');
ulElement.innerHTML = datas.map((data) => setLiElement(data)).join('');
}
function setLiElement(data){
testyear = data.baseYear;
return `<li><h1>${data.beachName} ${data.beachType}</h1></li> <p><h3>검사항목:${data.measureItem} 수치:${data.measureValue} 판정:${data.suitabilityFlag}</h3></p>`;
}
</script>
<style>
body{
background-image: url('https://a.cdn-hotels.com/gdcs/production123/d1230/d3ed36fc-c77c-4843-9b5e-7a5bfe80151d.jpg');
background-repeat: no-repeat;
background-size: cover;
color:white;
text-shadow: 2px 2px 2px rgb(0, 0, 0);
}
li{
background-color: rgb(0, 0, 0);
opacity: 0.8;
}
h3{
background-color: rgb(48, 167, 83);
opacity: 0.8;
}
</style>
<title>json</title>
</head>
<body>
<h1 style="color:rgb(255, 230, 0)">어디가 깨끗한 해수욕장일까?</h1>
<h2>2021 제주도 해수욕장 수질검사(JEJU DATA HUB)</h2>
<ul id='dataseries'>
<li></li>
</ul>
</body>
</html>
'웹 개발 > 🌐 JavaScript' 카테고리의 다른 글
동기, 비동기(콜백함수) (2) | 2022.11.26 |
---|---|
JavaScript | classList,dataset,map (0) | 2022.11.17 |
JavaScript | 주석,에러처리,index,콜스택,settimeout,비동기 (0) | 2022.11.17 |
JavaScript | 이벤트타입,이벤트리스너,이벤트객체,이벤트전파,iterable,generator,spread,set,map,operator (0) | 2022.11.11 |
JavaScript | 함수,오브젝트,클래스,상속,래퍼객체 (0) | 2022.11.09 |