320x100
320x100

콜백

: 나중에 호출할 함수

: 특정 함수의 실행이 완료 되면서 실행되는 함수

: 특정 함수 내에서 실행되는 함수

function loadScript(src, callback) {
  let script = document.createElement('script');
  script.src = src;

  script.onload = () => callback(script);

  document.head.append(script);
}
function loadScript(src, callback) {
  let script = document.createElement('script');
  script.src = src;
  script.onload = () => callback(script);
  document.head.append(script);
}

loadScript('https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js', script => {
  alert(`${script.src}가 로드되었습니다.`);
  alert( _ ); // 스크립트에 정의된 함수
});

 

 

 

 

콜백 속 콜백

: 콜백 함수 안에서 콜백을 실행

loadScript('/my/script.js', function(script) {

  loadScript('/my/script2.js', function(script) {

    loadScript('/my/script3.js', function(script) {
      // 세 스크립트 로딩이 끝난 후 실행됨
    });

  })

});

 

 

 

 

에러 핸들링 (오류 우선 콜백)

: 함수 실행 중 발생하는 에러를 처리

loadScript('/my/script.js', function(error, script) {
  if (error) {
    // 에러 처리
  } else {
    // 스크립트 로딩이 성공적으로 끝남
  }
});

 

 

 

 

 

멸망의 피라미드 (콜백 지옥)

: 함수의 호출이 중첩되면서 코드가 깊어지는 코드

: 비동기 동작이 하나씩 추가 될 때마다 중첩호출이 만들어내는 피라미드가 오른쪽으로 커짐

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('1.js', step1);

function step1(error, script) {
  if (error) {
    handleError(error);
  } else {
    // ...
    loadScript('2.js', step2);
  }
}

function step2(error, script) {
  if (error) {
    handleError(error);
  } else {
    // ...
    loadScript('3.js', step3);
  }
}

function step3(error, script) {
  if (error) {
    handleError(error);
  } else {
    // 모든 스크립트가 로딩되면 다른 동작을 수행합니다. (*)
  }
};

 

 

 

 

프라미스 (Promise)

- 제작코드

: 원격에서 실행되는 코드

 

- 소비코드

: 제작코드의 결과를 기다렸다가 실행되는 코드

 

- 프라미스

: 제작코드와 소비코드를 이어주는 자바스크립트 객체

: 시간이 얼마나 걸리든 상관없이 약속한 결과를 만들어냄

let promise = new Promise(function(resolve, reject) {
  // executor (제작 코드)
});

: new Promise에 전달되는 함수는 executer (실행자 / 실행함수)라고 함

: executer는 new Promise가 만들어질때 자동으로 실행되며 결과를 최종적으로 만들어내는 제작코드를 포함함

 

- resolve (value)

: 작업이 성공적으로 끝난 경우 그 결과를 나타내는 value와 함께 호출

 

- reject (error)

: 작업 중 에러 발생 시 에러 객체를 나타내는 error와 함께 호출

 

 

 

 

 

Promise의 상태와 단계

- state

: pending (보류) > resolve 호출 > fulfilled (result로 value 반환)

: pending (보류) > reject 호출 > rejected (result로 error 반환)

 

let promise = new Promise(function(resolve, reject) {
  // 프라미스가 만들어지면 executor 함수는 자동으로 실행됩니다.

  // 1초 뒤에 일이 성공적으로 끝났다는 신호가 전달되면서 result는 'done'이 됩니다.
  setTimeout(() => resolve("done"), 1000);
});

let promise = new Promise(function(resolve, reject) {
  // 1초 뒤에 에러와 함께 실행이 종료되었다는 신호를 보냅니다.
  setTimeout(() => reject(new Error("에러 발생!")), 1000);
});

 

 

※ 프라미스는 resolve나 reject 중 하나를 반드시 호출해야함

: 처리가 끝난 프라미스에 resolve와 reject를 호출하면 무시됨 

let promise = new Promise(function(resolve, reject) {
  resolve("done");

  reject(new Error("…")); // 무시됨
  setTimeout(() => resolve("…")); // 무시됨
});

 

 

 

 

resolve, reject 즉시 호출하기

let promise = new Promise(function(resolve, reject) {
  // 일을 끝마치는 데 시간이 들지 않음
  resolve(123); // 결과(123)를 즉시 resolve에 전달함
});

: 프라미스 객체의 state와 result 프로퍼티는 내부 프로퍼티이므로 개발자가 직접 접근할 수 없음

: .then, .catch, .finally를 메서드를 사용하면 접근 가능 

 

 

 

 

 

소비코드

- .then

: 프라미스가 이행되었을 때 실행되는 함수를 불러오는 메서드

promise.then(
  function(result) { /* 결과(result)를 다룹니다 */ },
  function(error) { /* 에러(error)를 다룹니다 */ }
);
let promise = new Promise(function(resolve, reject) {
  setTimeout(() => resolve("done!"), 1000);
});

// resolve 함수는 .then의 첫 번째 함수(인수)를 실행합니다.
promise.then(
  result => alert(result), // 1초 후 "done!"을 출력
  error => alert(error) // 실행되지 않음
);
let promise = new Promise(resolve => {
  setTimeout(() => resolve("done!"), 1000);
});

promise.then(alert); // 1초 뒤 "done!" 출력

 

- .catch

: 에러가 발생한 경우만 다룰때 사용하는 메서드

: .then(null, errorHandlingFunction)과 같이 null을 인수로 전달하는 것과 같음

let promise = new Promise((resolve, reject) => {
  setTimeout(() => reject(new Error("에러 발생!")), 1000);
});

// .catch(f)는 promise.then(null, f)과 동일하게 작동합니다
promise.catch(alert); // 1초 뒤 "Error: 에러 발생!" 출력

 

- .finally

: 프라미스가 이행되고 나서 결과에 상관없이 실행되는 메서드

: .finally 뒤에 .then과 .catch를 사용하여 오류처리 등등을 할 수 있음

new Promise((resolve, reject) => {
  setTimeout(() => resolve("결과"), 2000)
})
  .finally(() => alert("프라미스가 준비되었습니다."))
  .then(result => alert(result)); // <-- .then에서 result를 다룰 수 있음

 

 

 

 

 

 

 

Refference

 

콜백

 

ko.javascript.info

 

프라미스

 

ko.javascript.info

 

 

 

 

 

 

300x250
728x90