promise chaining

.esc·2021년 2월 18일
0

Promise chaining

여러 함수가 순차적으로 동작이 진행되길 원하는 경우 promise chaining을 사용해 비동기 처리할 수 있다.
promise.then()을 호출하면 promise가 반환되기 때문에 .then()을 또 호출할 수 있다.

new Promise(function(resolve, reject) {
  setTimeout(() => resolve(1), 1000);
}).then(function(result) {
  alert(result);
  return result * 2;
}).then(function(result) {
  alert(result);
  return result * 2;
}).then(function(result) {
  alert(result);
  return result * 2;
});

result.then(handler)체인에 따라 전달되므로 alert창에 1, 2, 4가 순서대로 출력된다.

promise 반환

.then(handler)promise를 생성하거나 반환할 수도 있다.
이어지는 .then(handler)promise가 처리될 때까지 기다리다가 처리가 완료되면 그 결과를 받는다.

new Promise(function(resolve, reject) {
  setTimeout(() => resolve(1), 1000);
}).then(function(result) {
  alert(result);
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve(result * 2), 1000);
  });
}).then(function(result) {
  alert(result);
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve(result * 2), 1000);
  });
}).then(function(result) {
  alert(result);
  return result * 2;
});

alert창에 1, 2, 4가 1초 간격으로 출력된다.


연습

https://velog.io/@esc/promiseloadScript()에 promise chaining 사용해보기

  • loadScript()
function loadScript(scriptUrl) {
  return new Promise(function(resolve, reject) {
    let script = document.createElement('script');
    script.src = scriptUrl;

    script.onload = () => resolve(scriptUrl);
    script.onerror = () => reject(new Error("error!"));

    document.head.append(script);
  });
};
  • promise chaining 사용
loadScript('./script.js')
  .then(script => loadScript('./script2.js'))
  .then(script => loadScript('./script3.js'))
  .then(script => {
    newFunc();
    two();
    three();
  });
  1. loadScript()를 호출할 때마다 promise가 반환된다.
  2. 다음 .then은 반환된 promise가 이행되었을 때 실행된다.

fetch + chaining

let promise = fetch('https://jsonplaceholder.typicode.com/users/5')
  .then(response => response.json())
  .then(user => fetch(`https://api.github.com/users/${user.username}`))
  .then(response => response.json())
  .then(githubUser => new Promise(function(resolve, reject) {
    let img = document.createElement('img');
    img.src = githubUser.avatar_url;
    document.body.append(img);

    setTimeout(() => {
      img.remove();
      resolve(githubUser);
    }, 3000);
  }))
  .then(githubUser => console.log(`username: ${githubUser.login}`));
  1. fetch를 사용해 서버에 네트워트 요청을 보내면 promise가 반환된다.
  2. 서버가 헤더와 함께 응답을 보내면 promiseresponse객체와 함께 이행된다.
    (response 전체가 완전히 다운로드 되기 전에 이행상태가 되어버린다.)
  3. .then을 사용해 response 전체가 다운로드 된 후에 json형태로 파싱한다.
  4. fetch를 사용해 네트워크 요청을 보낸다.
  5. json형태로 파싱한다.
  6. 체인을 확장할 수 있도록 promise객체를 생성한다.
  7. 다음 .then은 이 promise객체를 기다린다.
  • 재사용 가능한 함수로 분리하기
function loadJson(url) {
  return fetch(url)
    .then(res => res.json());
}

function loadGighubUser(name) {
  return fetch(`https://api.github.com/users/${name}`)
    .then(res => res.json());
}

function showAvatar(githubUser) {
  return new Promise(function(resolve, reject) {
    let img = document.createElement('img');
    img.src = githubUser.avatar_url;
    document.body.append(img);

    setTimeout(() => {
      img.remove();
      resolve(githubUser);
    }, 3000);
  });
}

loadJson('https://jsonplaceholder.typicode.com/users/5')
  .then(user => loadGighubUser(user.username))
  .then(showAvatar)
  .then(githubUser => console.log(`username: ${githubUser.login}`));

참조

https://ko.javascript.info/promise-chaining
https://jsonplaceholder.typicode.com/

profile
front-end

0개의 댓글