https://ko.javascript.info/destructuring-assignment
객체나 배열을 변수로 분해할 수 있게 한다.
// 이름과 성을 요소로 가진 배열 let arr = [1000, ["Hojun", "Lee"]] // 구조 분해 할당을 이용해 // firstName엔 arr[0]을 // surname엔 arr[1]을 할당하였습니다. let [계좌잔고, [firstName, surname]] = arr; console.log(계좌잔고); console.log(firstName); console.log(surname);
-> 1000
-> 'Hujun'
-> 'Lee'
let a = [[1, 2], [3, 4], [5, 6]] for (let [i, j] of a){ console.log(i, j); }
-> 1 2
-> 3 4
-> 5 6
에러가 발생하며 스크립트는 바로 중단된다.
try { alert('try 블록 시작'); // (1) <-- lalala; // 에러, 변수가 정의되지 않음! alert('try 블록 끝(절대 도달하지 않음)'); // (2) } catch(err) { alert(`에러가 발생했습니다!`); // (3) <-- }
에러 발생시 바로 캐치로 이동한다.
let json = "{ bad json }"; try { let user = JSON.parse(json); // <-- 여기서 에러가 발생하므로 alert( user.name ); // 이 코드는 동작하지 않습니다. } catch (e) { // 에러가 발생하면 제어 흐름이 catch 문으로 넘어옵니다. alert( "데이터에 에러가 있어 재요청을 시도합니다." ); alert( e.name ); alert( e.message ); }
throw 연산자
try 속에서 에러가 발생되면 catch로 가게 한다.
let json = '{ "age": 30 }'; // 불완전한 데이터 try { let user = JSON.parse(json); // <-- 에러 없음 if (!user.name) { throw new SyntaxError("불완전한 데이터: 이름 없음"); // (*) } alert( user.name ); } catch(e) { alert( "JSON Error: " + e.message ); // JSON Error: 불완전한 데이터: 이름 없음 }
후속 처리 메서드
try { ... 코드를 실행 ... } catch(e) { ... 에러 핸들링 ... } finally { ... 항상 실행 ... }
try
: 두 개의 콜백함수를 인수로 전달받는다. 첫번째는 promise가 성공(resolve) 했을 때, 두번 째는 실패(rejected)했을 때 호출된다.
catch
: 한 개의 콜백함수를 인수로 전달받는다. promise가 rejected일 때만 콜백함수가 호출된다.
finally
: promise의 성공(resolve)과 실패(rejected)에 관계없이 무조건 한 번 호출된다.
(공통적으로 수행해야 할 처리 내용이 있을 때 유용하다.)
try { alert( 'try 블록 시작' ); if (confirm('에러를 만드시겠습니까?')) 이상한_코드(); } catch (e) { alert( 'catch' ); } finally { alert( 'finally' ); }
만약 이런게 없으면 로그인하다 실패하면 스크립트가 멈춘다!
에러가 발생할 때 서버가 멈추면 안되니까 이렇게 작성을 한다.
견고한 코드를 짜기 위해서!
https://paullabworkspace.notion.site/13-promise-async-await-b5d46d419fb74968bdd0f11da3174141
콜백: 함수를 인자로 넘겨주는 것
멸망의 피라미드
// 정리 전 콜백 지옥 loadScript('1.js', function(error, script) { if (error) { handleError(error); } else { // ... loadScript('2.js', function(error, script) { if (error) { handleError(error); } else { // ... loadScript('3.js', function(error, script) { if (error) { handleError(error); } else { // 모든 스크립트가 로딩된 후, 실행 흐름이 이어집니다. (*) } }); } }) } });
// 정리 후
loadScript("/article/promise-chaining/one.js")
.then(script => loadScript("/article/promise-chaining/two.js"))
.then(script => loadScript("/article/promise-chaining/three.js"))
.then(script => {
// 스크립트를 정상적으로 불러왔기 때문에 스크립트 내의 함수를 호출할 수 있습니다.
one();
two();
three();
});
언제 불러줄지는 모르겠지만 불러주겠다(콜백)고 약속하는 것.
비동기적으로 약속.
비동기 처리 상태와 처리 결과를 관리하는 객체이다.
(노드할거라면 꼭 알아야한다.)
// 모던자바스크립트 예제 let promise = new Promise(function(resolve, reject) { // 프라미스가 만들어지면 executor 함수는 자동으로 실행됩니다. // 1초 뒤에 일이 성공적으로 끝났다는 신호가 전달되면서 result는 'done'이 됩니다. setTimeout(() => resolve("끝남!"), 1000); }); console.log('hello world'); console.log(promise);
비동기적이라는 것을 확실하게 알 수 있다.
let promise = new Promise(function(resolve, reject) { setTimeout(() => resolve("끝남!"), 3000); }); console.log('hello world'); promise.then(v => console.log(v)); console.log('hello world2'); // hello world // hello world2 // 끝남!
노드에서 많이 쓰게 될 것..
// 모던자바스크립트 예제 //프로미스를 하나 만들고 리절브에 1을 호출 1초후에 그 이후에 new Promise(function(resolve, reject) { setTimeout(() => resolve(1), 1000); // (*) //리절트가 들어가게됨 리절브의 (1) }).then(function(result) { // (**) //1이 출력이 되고 리턴에서2를 곱함 alert(result); // 1 return result * 2; //then으로 받아서 위에서 리턴해준 값을 넣어 }).then(function(result) { // (***) alert(result); // 2 return result * 2; }).then(function(result) { alert(result); // 4 return result * 2; });
// 모던자바스크립트 예제 //성공(resolve) 실패(reject) let p = new Promise(function(resolve, reject) { //성공했을 때 10초 후에 작동 setTimeout(() => resolve(1), 10000); // (*) }); //일단 진행 console.log('hello world'); //아직 p가 실행이 안되어서 대기 - 10초가 지나면 얘도 하나씩 실행 let p2 = p.then(function(result) { // (**) console.log(result); // 1 return result * 2; }); //얘도 일단 진행 console.log('hello world2'); //얘도 일단 대기 let p3 = p2.then(function(result) { // (***) console.log(result); // 2 return result * 2; }); console.log('hello world3'); let p4 = p3.then(function(result) { console.log(result); // 4 return result * 2; });
promise 체이닝
(딥다이브 856p)
// 모던자바스크립트 예제 // 다음 예제는 promise 체이닝이 아님! let promise = new Promise(function(resolve, reject) { setTimeout(() => resolve(1), 1000); }); promise.then(function(result) { alert(result); // 1 return result * 2; }); promise.then(function(result) { alert(result); // 1 return result * 2; }); promise.then(function(result) { alert(result); // 1 return result * 2; });
// 모던자바스크립트 예제 (살짝 수정) new Promise(function(resolve, reject) { setTimeout(() => reject('error'), 1000); }).then(function(result) { alert(result + ' : 잘 수행!'); return result + 'one'; }).catch(function(result) { alert(result + ' : 애러 발생!'); // 1 return result + 'two'; }).then(function(result) { alert(result + ' : 잘 수행!'); // 2 return result + 'three'; });
동기(synchronous : 순서대로)
비동기(Asynchronous : 순서대로가 아닌.)
fetch는 promise반환하기 때문에 then을 통해 resolve한 reponse 객체를 받을 수 있다.
네트워크 요청 시 promise를 자주 사용
fetch는 클라이언트 사이드 Web API이다.(비교적 최근에 추가되었다.)
fetch를 사용해 원격 서버에서 사용자 정보를 가져온다.
서버에서 들어오는 값은 변화되기 때문에 저장할 수 없다. 받아와야 한다.
fetch('https://raw.githubusercontent.com/ paullabkorea/coronaVaccinationStatus/main/data/data.json') .then(function(response) { return response.json(); }) .then(function(json) { console.log(json); return json }) console.log(1); console.log(2);
받아오는데 좀 지연이 되니까 콘솔을 먼저 찍고, 그 다음에 나온다.
1차 접종 퍼센트를 구해주세요!
fetch('https://raw.githubusercontent.com/paullabkorea/coronaVaccinationStatus/main/data/data.json') .then(function(response) { return response.json(); }) .then(function(json) { console.log(json); return json }) .then(function(json) { console.log(json.filter(s => s['시·도별(1)'] === '전국').map(obj => obj[1차 접종 퍼센트'])); return })
promise - api
https://ko.javascript.info/promise-api.json()
https://developer.mozilla.org/en-US/docs/Web/API/Response/json
syntactic sugar - 단순 편의문법
동기적(순차적)으로 비동기적 처리를 동기적인 모습의 코드로 간단하고 순차적으로 읽어 내릴 수 있어서 편리하다.
즉, 후속처리 메서드 없이 마치 동기 처리처럼 promise가 처리 결과를 반환하도록 구현할 수 있다.
async function f() { return 100; } f().then(alert);//100
async를 붙이면 promise처럼 쓸 수 있다. 비동기적으로!
await: promise가 이행될 때까지 기다린다.
// 모던 자바스크립트 예제 (살짝 수정) async function f() { return 100; } //result에는 앞에 return값이 들어간다. f().then(function(result) { // (**) alert(result); // 1 return result * 2; }).then(function(result) { // (***) alert(result); // 2 return result * 2; }).then(function(result) { alert(result); // 4 return result * 2; });
-> 100 200 400
// 모던 자바스크립트 예제 async function f() { let promise = new Promise((resolve, reject) => { setTimeout(() => resolve("완료!"), 1000) }); let result = await promise; // promise가 이행될 때까지 기다림 (*) alert(result); // "완료!" } f();
여기에서 만큼은 기다려야 한다.(결과로 무언가를 할거니까)
await은 async 함수 안에서만 동작했는데, 이제 밖에서도 된다.
function one(){ two(); } function two(){ three(); } function three(){ console.log('end'); } one() //end
스택
후입선출: LIFO (Last in first out)
나중에 넣은게 먼저 빠진다.
큐
선입선출: FIFO(First in first out)
먼저 넣은게 먼저 빠진다.
비동기에 대한 내용이 어려울 것이라고 생각해서 나름 미리 동영상도 봤는데, 상상이상으로 어려웠다. 그리고 어제 수업과는 달리 꼭 알아야하는 내용이라고 계속 강조하셔서 더 머리가 하얘졌다. 중요한데 나는 이해 못하고 있다는 생각을 하니 답답했다. 그래도 다른 분들이 계속 격려해주고, 함께 공부하는 분들과 어려운게 맞다고 힘내자고 말하는 과정에서 이런 답답함이 많이 해소가 된 것 같다. 이제 자바스크립트 시작한지 2주도 안됐는데 이 정도면 하루하루 가파르게 성장하고 있다고 생각한다. 너무 조급해하지말고, 이해 안 되는 부분이 있으면 책을 보거나 한번더 물어봐서라도 천천히 공부해나가자.
잘한점
고칠점