반응형

 


async / await

 

비동기 함수인 fetch를 이용하면, json 파일을 읽을 수 있다.

입력 칸에 색을 입력한 후 버튼을 클릭하면, 

해당 색에 해당하는 헥사 코드를 json 데이터에서 찾아 화면에 나타내는 코드를 async/await로 작성

const inputElem = document.querySelector('#inputColor');
const buttonElem = document.querySelector('#buttonSubmit');
const hexaCodeElem = document.querySelector('#hexaCode');

async function getHexaCode(e) {
  // 새로고침 방지
  e.preventDefault();
  const userInputColor = inputElem.value;

  // await를 반드시 fetch(), json() 앞에 붙여야 함
  const result = await fetch('data.json');
  const datas = await result.json();

  // 배열의 요소 중, color 가, 사용자가 입력한 색과 일치하는 요소를 찾음.
  const findData = datas.find(data => data.color === userInputColor);

  // 찾은 요소는 객체인데, 그 value값이 헥사코드임.
  hexaCodeElem.innerHTML = findData.value;
  
  // 참고로, 아래 코드를 추가하면 색상도 반영됨 (채점과는 무관합니다).
  hexaCodeElem.style.color = findData.value;
}

buttonElem.addEventListener('click', getHexaCode);

 

 

 


Fetch API 사용하기

fetch() 이용하며 헤더를 반드시 명시한다.

body에 JSON.stringify()를 사용해서 유저 정보(“첫번째 참가자”)라는 name을 서버에 업데이트

fetch('https://reqres.in/api/users', {
  method: 'POST',
  headers: { 'Content-type': 'application/json' },
  body: JSON.stringify({
    name: '첫번째 참가자',
  }),
})

 

response.ok 는 HTTP Status code가 200-299 사이면 true, 그외는 false

만약 res.ok일 경우 “Success!” 라는 메시지와 함께 res.json()을 반환하고,

ok가 아닐 경우, “failed”라는 메시지를 콘솔에 띄운다.

//fetch()의 인자로 'https://reqres.in/api/users' 라는 가짜 사용자 정보 API url을 패스.
fetch('https://reqres.in/api/users', {
  method: 'POST',
  //3. 헤더를 반드시 명시합니다.
  headers: { 'Content-type': 'application/json' },
  //4.body에 `JSON.stringify()`를 사용해서 유저 정보(Object)를 서버에 업데이트.
  body: JSON.stringify({
    name: '첫번째 참가자',
  }),
})
  .then(res => {
    // response.ok는 HTTP Status code가 200-299 사이면 true, 그외는 False.
    // 만약 res.ok일 경우 "Success!" 라는 메시지와 함께 `res.json()`을 반환하고,
    if (res.ok) {
      console.log('success!');
      return res.json();
    }
    // ok가 아닐 경우, "failed"라는 메시지를 콘솔에 띄운다.
    else {
      console.log('failed');
    }
  })
  .then(data => console.log(data))
  .catch(error => console.log('Error'));

 

 

 


await 이미지 띄우기

1. 구글에서 이미지 주소를 가져와 fetch인자로 불러온다.

import 'babel-polyfill';

async function fetchImage() {
  // fetch() 메서드를 호출하여 구글에 검색된 이미지를 가져오고 변수(response)에 저장. 
  // 이때 await을 사용
  
  let response = await fetch(
    'https://pbs.twimg.com/profile_images/799445590614495232/ii6eBROd_400x400.jpg'
  );

  const error = false;

  if (!response.ok || error) {
    throw new Error(`HTTP error! status: ${response.status}`);
  } else {
    document.write("here's the image");
    return await response.blob();
  }
}

2. then()블록을 사용하여 promise가 성공적인 실행에 응답하며 catch()로 에러가 발생했을때 대처하는 코드를 작성

// then() 블록을 사용하여 promise가 성공적인 실행에 응답하고 에러가 발생했을때 catch를 하는 코드를 작성하세요.

fetchImage()
  //then()의 인자로 blob을 받는다.
  .then(blob => {
    //실행코드
    // 이미지를 변환해서 <img>의 src를 객체 URL로 설정하여 이미지에 html에 표시되도록 한다.

    // Blob 객체를 가리키는 객체 URL을 생성
    let objectURL = URL.createObjectURL(blob);

    // blob(이미지)을 표시할 <img> 요소를 만든다.
    let image = document.createElement('img');

    // <img>의 src를 객체 URL로 설정하여 이미지에 표시되도록 한다.
    image.src = objectURL;

    // ADOM에 <img> 요소 추가
    document.body.appendChild(image);
  })
  .catch(error => console.log(error));

반응형
반응형

 


Promise

 

Promise

자바스크립트에서 비동기 함수를 다루는 방법

 

Promise 생성문법

var myPromise1 = new Promise(function(resolve, reject) {
  resolve(1);
});

myPromise1.then();  //이행

 

Promise의 resolve(이행)와 reject(거부)

Promise라는 object를 갖고 then이란 콜백 함수를 요청하면 사용자 데이터를 등록한 대로 콜백 함수를 불러줄 수 있다.

var myPromise2 = new Promise(function(resolve, reject) {
  reject(1);		
});

myPromise2.then();	// 거부

 

 

예제1

getData()함수에 new Promise()를 호출할 때 콜백 함수의 인자를 resolve, reject로 선언.

이때, resolve를 실행해서 아래 선언된 메시지를 resolve 인자값으로 넘기기.

// new Promise()를 호출할 때 콜백 함수의 인자를 resolve, reject로 선언.
function getData() {
  return new Promise(function (resolve, reject) {
    //resolve를 실행해서 아래 선언된 메시지(data)를 resolve 인자 값으로 넘김.
    var data = 'javascript promise';
    resolve(data);
  });
}

// then을 이용해서 resolve()의 결과 값 data를 resolvedData로 받기.
getData().then(function (resolvedData) {
  document.write(resolvedData);
});

 

 

예제2

 

getPosts() 함수 작성 

posts 의 내용을 불러와 index.html에 표시하는 코드

//posts 변수
const posts = [
  { title: 'Post 1', body: '첫번째 게시글입니다.' },
  { title: 'Post 2', body: '두번째 게시글입니다.' },
  { title: 'Post 3', body: '세번째 게시글입니다.' },
  { title: 'Post 4', body: '네번째 게시글입니다.' },
  { title: 'Post 5', body: '다섯번째 게시글입니다.' },
];

function getPosts() {
  //setTimeout()를 사용해서 1초 후에 posts element를 rendering 합니다.
  setTimeout(() => {
    let output = '';
    //위에 정의된 posts 내의 게시글 제목과 내용을 forEach()을 사용해서 rendering 합니다.
    posts.forEach(post => {
      output = output + `<li>${post.title}<br> 내용: ${post.body} </li>`;
    });
    //rendering 된 게시글을 document.body.innerHTML을 사용해서 html에 띄어줍니다.
    document.body.innerHTML = output;
  }, 1000);
}

 

createPost() 함수 작성

이행 상태가 되면 then()을 이용하여 처리 결과 값을 받을 수 있다.

실패 상태가 되면 실패한 이유(실패 처리의 결과 값)를 catch()로 받을 수 있다.

function createPost(post) {
  //Promise를 생성해서 resolve와 reject를 인자로 받습니다.
  return new Promise(function (resolve, reject) {
    //Promise 내에 setTimeout으로 비동기 처리하는데,
    setTimeout(() => {
      // createPost()함수에 인자로 받아온 post를 push할 때
      posts.push(post);
      const error = false;
      // 에러없이 성공적으로 호출되면(if(!error)) `resolve`를 실행
      if (!error) resolve();
      // 그렇지 않으면 에러를 받아들이는 `reject`를 2초 후에 실행
      else reject('error: wrong');
    }, 2000);
  });
}

createPost({ title: 'Post N', body: 'N번째 게시글입니다.' })
  .then(getPosts)
  .catch(err => console.log(err));

 

 

 


fetch 이용해 json데이터 가져오기

 

 

비동기 함수인 fetch를 이용하면, json 파일을 읽을 수 있다.

function showHexaCode(e) { 
  // 새로고침 방지
  e.preventDefault()
  
  const userInputColor = inputElem.value 
  
  // fetch -> response.json() 하는 과정은 고정입니다 (번거롭지만, 매번 해 주어야 함).
  // 물론 response 대신 res 등으로 변수명은 바꾸어도 됩니다.
  fetch('data.json')
    .then(response => response.json())
    .then(datas => {
      // 배열의 요소 중, color 가, 사용자가 입력한 색과 일치하는 요소를 찾음. 
      const foundData = datas.find(data => data.color === userInputColor)
      
      // 찾은 요소는 객체인데, 그 value값이 헥사코드임.
      hexaCodeElem.innerHTML = foundData.value
      
      // 참고로, 아래 코드를 추가하면 색상도 반영됨.
      hexaCodeElem.style.color = foundData.value
    })
  
}

const inputElem = document.querySelector('#inputColor')
const buttonElem = document.querySelector('#buttonSubmit')
const hexaCodeElem = document.querySelector('#hexaCode')

buttonElem.addEventListener("click", showHexaCode)

 

반응형
반응형

동기 처리 / 비동기 처리

동기처리 함수를 그대로 수행

// 동기처리 함수를 그대로 수행하는 `printImmediately()` 함수
function printImmediately(print) {
  print();
}

//동기처리
printImmediately(() => console.log('hello'));

 

특정 시간 이후에 비동기처리 콜백을 보내는 함수

//비동기 처리 Asynchronous callback
function printWithDelay(print, timeout) {
  // setTimeout을 이용해서 비동기 처리 함수를 완성
  setTimeout(() => {
    print();
  }, timeout);
}

// printWithDelay()를 실행해서 3초 늦게 "async callback" 문장을 띄우는 코드
printWithDelay(() => console.log('async callback'), 3000);

 


setTimeout 사용하는 함수

 

함수 실행 시, 3 -> 2-> 1-> “끝” 이 차례대로 출력(console.log)됨.

  • 3은 함수 실행 시 딜레이 없이 바로 출력되어야 합니다.
  • 2는 3이 출력된 1초 후 출력되어야 합니다.
  • 1은 2가 출력된 1초 후 출력되어야 합니다.
  • “끝”은 1이 출력된 1초 후 출력되어야 합니다.
  • 3,2,1은 숫자가 출력되어야 합니다. (문자열 아님)
function countDownThree() {
  console.log(3);
  setTimeout(() => console.log(2), 1000);
  setTimeout(() => console.log(1), 2000);
  setTimeout(() => console.log('끝'), 3000);
}

 

 

 


setTimeout 으로 디바운싱 구현하기

 

변화하는 도중(1초 이내에 다른 변화가 생김)에는 효과가 발생 안 하다가, 

멈출 시(1초 이상 변화가 없음) 효과가 발생하는 것을 디바운싱(debouncing) 이라고 한다.

 

// input 엘리먼트 가져옴
const nameElem = document.querySelector('#inputName')

let alertTimer
function alertWhenTypingStops() {
  // 앞선 타이머를 리셋
  if (alertTimer) {
    clearTimeout(alertTimer)
  }
  
  const name = nameElem.value
  // 타이머 시작
  alertTimer = setTimeout(() => alert(`입력된 이름: ${name}`), 1000)
}

// input 이벤트는 사용자가 값을 수정할 때마다 발생
nameElem.addEventListener("input", alertWhenTypingStops)

 

 


setTimeout 으로 쓰로틀링 구현하기

 

조건이 지속적으로 만족될 때에는 효과(점수 증가, api 요청 등)가 주기적으로 발생하다가,

멈출 시(조건 불만족) 효과가 멈추는 것을 쓰로틀링(throttling) 이라고 한다.

 

쓰로틀링은 코드 자체는 길지 않지만, 한 번에 이해하기는 어려울 수 있다.

코드를 보면서, 언제 true고 false인지, 타이머가 언제 생겨나고 끝나는지가 중요하다.

 

// 자유롭게 코드를 작성하여, 예시 화면이 구현되도록 해 보세요.

// input 엘리먼트 가져옴
const nameElem = document.querySelector('#inputName')


let isInThrottle
function increaseScoreDuringTyping() {
  if (isInThrottle) {
    return
  }
  
  isInThrottle = true
  
  // 타이머 세팅
  setTimeout(() => {
    const score = document.querySelector('#score')
    const newScore = parseInt(score.innerText) + 1
    score.innerText = newScore
    
    isInThrottle = false
  }, 500)
}

// input 이벤트는 사용자가 값을 수정할 때마다 발생
nameElem.addEventListener("input", increaseScoreDuringTyping)
반응형
반응형

https://developer.mozilla.org/ko/docs/Web/JavaScript/EventLoop

 

이벤트 루프 - JavaScript | MDN

JavaScript의 런타임 모델은 코드의 실행, 이벤트의 수집과 처리, 큐에 대기 중인 하위 작업을 처리하는 이벤트 루프에 기반하고 있으며, C 또는 Java 등 다른 언어가 가진 모델과는 상당히 다릅니다.

developer.mozilla.org

 

 

 

https://meetup.toast.com/posts/89

 

자바스크립트와 이벤트 루프 : NHN Cloud Meetup

자바스크립트와 이벤트 루프

meetup.toast.com

 

 

이벤트 루프

이벤트를 처리하는 반복되는 동작을 의미한다.

즉, 비동기 이벤트 동작을 처리하는 일련의 반복동작.

비동기 코딩이 어떤 순서로 수행되는지 이해할 수 있다.

 

 

 

 

이벤트루프 구성요소

 

콜 스택

작성된 함수들이 등록되는 LIFO 스택

이벤트 루프는 콜스택이 비어있을 때까지 스택의 함수를 실행한다.

 

 

메시지 큐

setTimeout 같은 지연 실행 함수를 등록하는 FIFO 큐

정해진 시간이 끝나면 콜스택이 비어있는 경우에 해당 함수를 콜스택에 추가한다.

 

 

 

잡 큐

Promise에 등록된 콜백을 등록하는 FIFO 큐

상위함수가 종료되기 전에, 콜스택이 비어있지 않더라도 잡큐에 등록된 콜백함수를 콜스택에 추가한다.

 

 

 

 

* setTimeout은 콜스택이 비어있을 때 실행된다.

* Promise는 상위함수가 종료되기 전에 실행된다.

 

 

function baz() {
  console.log('baz');
}

function bar() {
  console.log('bar');
}

function foo() {
    console.log('foo');
    setTimeout(bar, 0);
    baz();
}

foo();

위 코드의 실행순서는???

foo

baz

bar

 

그 이유는???

setTimeout은 비동기 동작으로 bar( ) 함수는 아무리 0초라 하더라도 메시지 큐에 들어간다.

콜스택에 foo( )까지 종료되어 콜스택이 비어있을 때 메시지 큐에서 콜스택으로 넘어간다. 

따라서 bar( )가 마지막에 실행되는 것이다.

반응형
반응형

Axios 와 Ajax

HTTP 비동기 통신 라이브러리

 

Axios 

웹 브라우저와 Node.js를 위한 HTTP 비동기 통신 라이브러리로, promise 기반으로 이루어져 있다.

즉, 백엔드와 프론트엔드 간 통신을 쉽게 하기 위해 Ajax(Asynchronous JavaScript and XML)처럼 사용된다.

 

Ajax

브라우저가 가지고 있는 XMLHttpRequest 객체를 이용하여 화면 전체를 새로 고침 하지 않고 변경된 일부 데이터만 로드하는 비동기 처리가 가능

 

 


Fetch 와 Axios

HTTP 요청을 처리하기 위한 자바스크립트의 라이브러리

 

Fetch

  • 자바스크립트에 내장되어 있기 때문에 별도의 import나 설치가 필요하지 않다.
  • 인터넷 익스플로러 버전에서 지원하지 않는 경우가 있다.
  • JSON 자동 변환, 응답 시간 초과 설정 기능을 지원하지 않는다.

 

Axios

  • 별도의 import나 설치가 필요하다.
  • 브라우저 호환성이 뛰어나다.
  • JSON 자동 변환, 응답 시간 초과 설정 기능 등을 지원한다.

 


Axios 사용법

CRUD

Create, Read, Update, Delete

 

C : Create(생성) - POST
R : Read(조회) - GET
U : Update(수정) - PUT
D : Delete(삭제) - DELETE

 

 

(1) 라이브러리 추가

index.html 파일에 아래 axios 라이브러리 관련 스크립트를 추가한다.

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

 

(2) POST

POST는 새로운 자원을 생성할 때 사용

axios.post(url, data 객체)
axios.post('https://reqres.in/api/login', {
      email: 'eve.holt@reqres.in',
      password: 'cityslicka',
    })
    .then(response => {
      console.log(response);
      token.innerHTML = response.data.token
    });
}

 

 

(3) GET

GET은 자원을 요청할 때 사용

axios.get(url)
axios.get('https://reqres.in/api/users/2')
    .then((response) => {
      let res = response.data.data;
      name.innerHTML = res.first_name + " " + res.last_name;
      email.innerHTML = res.email;
});

 

 

(4) PUT

PUT은 자원을 갱신할 때 사용

axios.put(url, 수정할 data 객체)
// 수정할 데이터를 선언
const url = 'https://reqres.in/api/users/2'
const object = { "first_name": "White", "last_name": "Rabbit" , "email": "alice@elice.io" }

// axios.put을 호출하고 result에 반환되는 사용자 데이터를 저장
axios.put(url, object)
.then((response) => {
  console.log(response.data)
  const res = response.data
  name.innerHTML = res.first_name + ' ' + res.last_name
  email.innerHTML = res.email
  updateDate.innerHTML = res.updatedAt
})

 

(5) DELETE

DELETE는 자원을 삭제할 때 사용

axios.delete(url)
axios.delete("https://reqres.in/api/users/2").then((response) => {
    console.log(response);
    status.innerHTML = response.status;
});

 

반응형
반응형

async/await

  1. 기존의 비동기 처리 방식인 (1) callback (2) promise 의 단점을 보완하기 위해 등장한 문법.
  2. 가독성이 높아지고 .then 메서드 체인 없이도 순서가 있는 비동기 처리가 가능해졌다.
  3. async/await 함수의 리턴값은 항상 promise여야 한다. promise가 아닌 값이 리턴되면 Promise.resolve()로 감싸져 리턴된다.
  4. 에러 처리는 try-catch 구문을 사용한다.
async function asynFunc() {
    try {
        let data = await fetchData();
        let user = await fetchUser(data);
        return user;
    } catch (e) {
    	console.log("실패:", e);    
    }
}
  • function 키워드 앞에 async를 붙여 async 함수를 만든다.
  • async 함수 내에서 await 키워드를 사용하여 fetchData() 와 fetchUser() 순서로 비동기 처리한다.
  • 이 코드에서 fetchData() 와 fetchUser()는 Promise를 리턴해준다.
  • try 구문에서 만약 오류가 발생하면 코드실행을 중단하고, catch로 넘어가 에러처리를 한다.

 

 


 

 

fetch API

  1. 기존 XMLHTTPRequest 를 대체하는 HTTP 요청 API이다.
  2. ES6에 추가된 Promise를 리턴하도록 정의되었다.
  3. 네트워크 요청 성공시, promise는 response 객체를 resolve( )하고, 실패시 promise는 error객체를 reject( )한다.

 

let result = fetch(serverURL) // fetch API 호출하면 promise를 반환

result.then(response => {
    if(response.ok) {
        // 호출 성공시 실행할 코드 입력
        // ...
    }
})
.catch (error => {
    // 호출 실패시 실행할 코드 입력
    // ...
})

response.status : HTTP 상태코드가 저장된다.

response.ok : HTTP 상태코드가 200~209 이면 true를 저장하고, 아니면 false를 저장한다. 

response.url : 요청한 url 정보를 담는다.

response.header : Response객체의 헤더 정보를 얻을 수 있다.

response.blob() : 파일을 요청했다면 여기에 파일이 들어있다.

response.json() 메서드 : body 정보를 json으로 만드는 Promise를 반환하는 비동기 함수이다.

 

 

fetch를 Post 요청

fetch (url, options)로 옵션사항으로 post 방식을 선택할 수 있다.

옵션에는 headers / body 정보도 함께 전달 가능하다.

fetch(serverURL, {
    method: 'post',
    headers: 
    {
        'Content-Type': 'application/json;charset=utf-8',
        Authentication: 'mysecret'
    },
    body: JSON.stringify(formData)
})
.then(response => {
	return response.json();
})
.then(json => {
	console.log('POST 요청 결과', json)
})

 

 

Post 정보 조합하기

...

반응형
반응형

Promise

자바스크립트에서 Promise API는 비동기 API이다.

따라서 setTimeout은 Task queue에 저장되는 것과 달리, Promise API는 Job queue에 저장된다.

job que가 task que보다 우선순위 높기 때문에 아래와 같은 결과가 나온다.

setTimeout(() => {
	consoloe.log("타임 아웃1")
}, 0);

Promise.resolve().then( () => console.log("프로미스1"));

setTimeout(() => {
	consoloe.log("타임 아웃2")
}, 0);

Promise.resolve().then( () => console.log("프로미스2"));


// 출력
// 프로미스1 프로미스2
// 타임 아웃1 타임 아웃2

 

 


 

Promise의 작업 상태

new Promise( )로 프로미스를 생성하고 종료 될 때까지 3가지 상태를 갖는다.

 

(1) Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태

new Promise() 메서드를 호출하면 대기(Pending) 상태가 된다. 이때 콜백 함수를 선언할 수 있고, 콜백 함수의 인자는 resolve, reject다.

new Promise(function(resolve, reject) {
  // ...
});

 

(2) Fulfilled(이행 == 완료) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태

여기서 콜백 함수의 인자 resolve를 아래와 같이 실행하면 이행(Fulfilled) 상태가 된다.

new Promise(function(resolve, reject) {
  resolve();
});

이행 상태가 되면 아래와 같이 then()을 이용하여 처리 결과 값을 받을 수 있다.

function getData() {
  return new Promise(function(resolve, reject) {
    var data = 100;
    resolve(data);
  });
}

// resolve()의 결과 값 data를 resolvedData로 받음
getData().then(function(resolvedData) {
  console.log(resolvedData); // 100
});

 

(3) Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태

reject를 아래와 같이 호출하면 실패(Rejected) 상태가 된다.

new Promise(function(resolve, reject) {
  reject();
});

실패 상태가 되면 실패한 이유(실패 처리의 결과 값)를 catch()로 받을 수 있다. (reject보다는 catch를 추천함)

function getData() {
  return new Promise(function(resolve, reject) {
    reject(new Error("Request is failed"));
  });
}

// reject()의 결과 값 Error를 err에 받음
getData().then().catch(function(err) {
  console.log(err); // Error: Request is failed
});

 

 

Promise.resolve와 Promise.reject

Promise.resolve함수는 Promise를 바로 반환한다.
Promise.reject함수는 실패한 Promise를 바로 반환한다.

Promise
    .resolve(10)
    .then(console.log)

Promise
    .reject("Error")
    .catch(console.log)

 

 

Promise로 then, catch, finally 코드

then ( ) 메서드: 성공했을 때, 실행할 콜백함수를 인자로 넘긴다.

catch ( ) 메서드: 실패했을 때, 실행할 콜백함수를 인자로 넘긴다.

finally ( ) 메서드: 성공/실패 여부와 상관없이 모두 실행할 콜백 함수를 인자로 넘긴다.

function getData() {
  return new Promise(function(resolve, reject) {
    $.get('url 주소/products/1', function(response) {
      if (response) {
        resolve(response);
      }
      reject(new Error("Request is failed"));
    });
  });
}

// 위 $.get() 호출 결과에 따라 'response' 또는 'Error' 출력
getData().then(function(data) {
  console.log(data); // response 값 출력
}).catch(function(err) {
  console.error(err); // Error 출력
}).finally(function() {
  console.log("promise 종료"); // 성공/실패 여부에 관계없이 항상 실행
});

 

 

 

Promise Chaning ( 여러 개의 프로미스 연결하기)

then() 메서드를 호출하고 나면 새로운 프로미스 객체가 반환된다. 따라서, 아래처럼 체인 형식으로 구현이 가능해진다.

 

new Promise(function(resolve, reject){
  setTimeout(function() {
    resolve(1);
  }, 2000);
})
.then(function(result) {
  console.log(result); // 1
  return result + 10;
})
.then(function(result) {
  console.log(result); // 11
  return result + 20;
})
.then(function(result) {
  console.log(result); // 31
});

프로미스 객체를 하나 생성하고 setTimeout()을 이용해 2초 후에 resolve()를 호출하는 예제

resolve()가 호출되면 프로미스가 대기 상태에서 이행 상태로 넘어가기 때문에 첫 번째 .then()의 로직으로 넘어감.

첫 번째 .then()에서는 이행된 결과 값 1을 받아서 10을 더한 후 그다음 .then() 으로 넘겨줌.

두 번째 .then()에서도 마찬가지로 바로 이전 프로미스의 결과 값 11을 받아서 20을 더하고 다음 .then()으로 넘겨줌.

마지막 .then()에서 최종 결과 값 31을 출력.

 

 

 

Promise.all

Promise 배열을 받아 모두 성공시 각 Promise의 resolved 값을 배열로 반환한다.

하나의 promise라도 실패할 시, 가장 먼저 실패한 promise의 실패 이유를 반환한다.

Promise.all([
    promise1,
    promise2,
    promise3
])
    .then(values => {
        console.log("모두 성공", values)
    })
    .catch(e => {
        console.log("하나라도 실패", e)
    })

 

 

 

 

 

 

 

반응형
반응형

자바스크립트의 비동기 처리

특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 자바스크립트의 특성으로,

자바스크립트가 싱글 스레드라서 비동기처리가 필요한 것이다!

멀티스레드인 자바는 하나의 스레드가 놀아도, 다른 스레드가 일할텐데 자바스크립트는 스레드가 하나라 쉴틈없이 일을 하는 것.

 

 

비동기 처리는 이벤트 루프와 콜스택(call stack)을 이용한다.

call stack에는 func1, func2... 가 쌓인다. 

그중 비동기 코드가 호출되면 webAPI를 통해 완료된 결과는 task queue에 저장되고, 

이벤트 루프는 call stack과 task queue를 감시하다가, call stack이 비워지면 task queue에 저장되어 있는 콜백함수를 call stack에 저장한다.

 

 

참고! 

[JavaScript] Task Queue말고 다른 큐가 더 있다고? (MicroTask Queue, Animation Frames)

 

[JavaScript] Task Queue말고 다른 큐가 더 있다고? (MicroTask Queue, Animation Frames)

자바스크립트에서 비동기 함수가 동작하는 원리에 대해서 공부했다면, Task Queue에 대해 들어보았을 것이다. Task Queue는 Web API가 수행한 비동기 함수를 넘겨받아 Event Loop가 해당 함수를 Call Stack에

velog.io

 

 

 

사례1) 제이쿼리의 ajax 또는 fetch

제이쿼리로 실제 웹서비스를 개발할 때, ajax 통신을 한다. 화면에 표시할 이미지나 데이터를 서버에서 불러와 표시해야 하는데, 이때 ajax 통신으로 해당 데이터를 서버로부터 가져온다.

function getData() {
	var tableData;
	$.get('https://domain.com/products/1', function(response) {
		tableData = response;
	});
	return tableData;
}

console.log(getData()); // undefined

$.get(url, function(response) {  })  

url에 HTTP get 요청을 보내 받아온 데이터를 response 인자에 저장된다.

 

Q. 콘솔에 getData()를 출력하면 undefined가 나오는 이유는?

A.  $.get()로 데이터를 요청하고 받아올 때까지 기다려주지 않고 다음 코드인 return tableData;를 실행했기 때문.

따라서, getData()의 결과 값은 초기 값을 설정하지 않은 tableData의 값 undefined를 출력

 

 

 

사례2) setTimeout(function() {    }, ms)

ms 시간만큼 기다렸다가 function을 실행하는 API. ms동안 기다리기만 하는게 아님. 그 다음줄의 코드를 실행하는 것.

// #1
console.log('Hello');
// #2
setTimeout(function() {
	console.log('Bye');
}, 3000);
// #3
console.log('Hello Again');

여기서  #1 출력 -> #3 출력 -> #2가 출력된다.

 

 

 


콜백 함수 Callback


콜백함수

비동기적으로 동작하는 경우에, 데이터가 준비된 시점에 원하는 동작을 수행하도록 콜백함수를 사용한다.

 

콜백지옥

서버에서 데이터 받아옴, 그 데이터로 파싱하여 id추출, id로 인증함, 인증결과를 화면에 표출함.

이 모든 과정을 비동기로 처리하면 아래와 같은 콜백 안에 콜백을 계속 물게 된다. 이게 콜백 지옥

$.get('url', function(response) {
	parseValue(response, function(id) {
		auth(id, function(result) {
			display(result, function(text) {
				console.log(text);
			});
		});
	});
});

 

콜백지옥의 해결책

ES6에서 제공하는 Promise과 ES8에서 제공하는 Async / Await

브라우저에서 제공하는 webAPI setTimeout, setInterval 등이 존재한다.

 

 

반응형

+ Recent posts