* 내용 스크랩

 

05. 콜백지옥과 비동기제어

 

- 콜백지옥은 콜백함수를 익명함수로 전달하는 과정이 반복되어 코드의 들여쓰기 수준이 깊어지는 현상

- 주로 이벤트처리나 서버 통신과 같이 비동기적인 작업을 수행하기 위해 이런 형태가 자주 등장함

- 동기적인 코드는 현재 실행중인 코드가 완료된 후에야 다음 코드를 실행하는 방식 

- 비동기적인 코드는 현재 실행중인 코드 완료 여부와 무관하게 즉시 다음 코드로 넘어감 

- 사용자의 요청에 의해 특정 시간이 경과되기 전까지 어떤 함수의 실행을 보류한다거나(setTimeout)

- 사용자의 직접적인 개입이 있을 때 함수를 실행하도록 대기한다거나 (addEventListener)

- 웹브라우저 자체가 아닌 별도의 대상에 무언가를 요청하고 응답이 왔을 때 함수를 실행하도록 대기하는 (XMLGttpRequest)

- 이런 별도의 요청, 실행 대기, 보류 등과 관련된 코드는 비동기적인 코드

 

// setTimeout 문법

var timeoutID = window.setTimeout(func[, delay, param1, param2, ...]);

var timeoutID = window.setTimeout(code[, delay]);

window.setTimeout(function, milliseconds);

// 예제 4-12

setTimeout(function(name){

  var coffeeList = name;

  console.log(coffeeList);

 

  setTimeout(function(name){

    coffeeList += ',' + name;

    console.log(coffeeList);

    

    setTimeout(function(name){

      coffeeList += ',' + name;

      console.log(coffeeList);

     

      setTimeout(function(name){

        coffeeList += ',' + name;

        console.log(coffeeList);

      },500,'카페라떼');

    },500,'카페모카');

  },500,'아메리카노');

},500,'에스프레소');

 

// 에스프레소

// 에스프레소, 아메리카노

// 에스프레소, 아메리카노, 카페모카

// 에스프레소, 아메리카노, 카페모카, 카페라떼

// 문제점 : 들여쓰기 수준이 깊어졌으며, 값이 전달되는 순서가 아래에서 위로 향하고 있어 어색하게 느껴짐

// 예제 4-13 - 기명함수로 변환

var coffeeList = '';

 

var addEspresso = function(name){

  coffeeList = name;

  console.log(coffeeList);

  setTimeout(addAmericano, 500, '아메리카노');

};

var addAmericano = function(name){

  coffeeList += ',' + name;

  console.log(coffeeList);

  setTimeout(addMocha, 500, '카페모카');

};

var addMocha = function(name){

  coffeeList += ',' + name;

  console.log(coffeeList);

  setTimeout(addLatte, 500, '카페라떼');

};

var addLatte = function(name){

  coffeeList += ',' + name;

  console.log(coffeeList);

};

  setTimeout(addEspresso, 500, '에스프레소');

 

// 가독성은 좋아졌지만, 일회성 함수라는 것이 단점

 

- setTimeout을 변수에 넣는 과정에서 메서드가 실행된다고 배웠는데, 위 예제에서 실행되지 않는 이유 

=> setTimeout을 함수안에 넣었기 때문에 함수를 실행하지 않는 이상 별도로 실행되지 않는다

 

// 예제 4-14 비동기 작업의 동기적 표현 - Promise

new Promise(function(resolve){

  setTimeout(function(){

    var name = '에스프레소';

    console.log(name);

    resolve(name);

},500);

}).then(function(prevName){

  return new Promise (function(resolve){

    setTimeout(function(){

      var name = prevName + '아메리카노';

      console.log(name);

      resolve(name);

    },500);

  });

}).then(function(prevName){

  return new Promise (function(resolve){

    setTimeout(function(){

      var name = prevName + '카페모카';

      console.log(name);

      resolve(name);

    },500);

  });

}).then(function(prevName){

  return new Promise (function(resolve){

    setTimeout(function(){

      var name = prevName + '카페모카';

      console.log(name);

      resolve(name);

    },500);

  });

 

- resolve 또는 reject 함수를 호출하는 구문이 있을 경우 둘 중 하나가 실행되기 전까지는 then 또는 오류구문(catch)으로 넘어가지 않음

 

// 예제 4-15 비동기작업의 동기적 표현 - Promise2

var addCoffee = function(name) {

  return function(prevName) {

    return new Promise(function(resolve){

      setTimeout(function(){

        var newName = prevName ? (prevName + ',' + name) : name;

        console.log(newName);

        resolve(newName);

      },500);

    });

  };

};

addCoffee('에스프레소')()          // 함수 addCoffee 안에 return값으로 내부함수가 있는구조기 때문에 함수 실행을 두번한다 

  .then(addCoffee('아메리카노'))

  .then(addCoffee('카페모카'))

  .then(addCoffee('카페라떼'));

 

- 함수 addCoffee안에 return값으로 내부함수가 있는 구조기 때문에 함수 실행을 두번한다 

- 이후 then의 두번째 함수의 인자로 이전 resolve값이 온다

 

// 예제 4-16 비동기작업의 동기적표현 - Generator

var addCoffee = function (prevName, name){

  setTimeout(function(){

    coffeeMaker.next(prevName? prevName + ',' + name : name);

  },500);

};

var coffeeGenerator = function* () {

  var espresso = yield addCoffee('', '에스프레소');

  console.log(espresso);

  var americano = yield addCoffee(espresso, '아메리카노');

  console.log(americano);

  var mocha = yield addCoffee(americano, '카페모카');

  console.log(mocha);

  var latte = yield addCoffee(mocha, '카페라떼');

  console.log(latte);

};

var coffeeMaker = coffeeGenerator();

coffeeMaker.next();  

 

- '*'이 붙은 함수가 Generator 함수

- 함수 실행시 Iterator가 반환되는데, Iterator는 next라는 메서드를 가지고 있음

- next메서드 호출시 가장 먼저 등장하는 yield에서 함수의 실행을 멈춤

- 이후 다시 next메서드를 호출하면 앞서 멈췄던 부분부터 시작해서 다음에 등장하는 yield에서 함수의 실행을 멈춤  

 

​

 

// 비동기작업의 동기적표현 - Promise+Async/await

var addCoffee = function(name){

  return new Promise(function(resolve){

    setTimeout(function(){

      resolve(name);

    },500);

  });

};

var coffeeMaker = async function(){

  var coffeeList = '';

  var _addCoffee = async function(name){

    coffeeList += (coffeeList ? ',' : '') + await addCoffee(name);

  };

  await _addCoffee('에스프레소');

  console.log(coffeeList);

  await _addCoffee('아메리카노');

  console.log(coffeeList);

  await _addCoffee('카페모카');

  console.log(coffeeList);

  await _addCoffee('카페라떼');

  console.log(coffeeList);

};

coffeeMaker();

 

- 비동기 작업을 수행하고자 하는 함수 앞에 async를 표기한다,

- 함수 내부에서 실질적인 비동기 작업이 필요한 위치마다 await 표기하는 것만으로 뒤의 내용을 Promise로 자동전환되며, 

해당 내용이 resolve된 이후에야 다음으로 진행된다 ( Promise then과 흡사한 효과를 얻을 수 있다 )

 
 
 
 
 
 
 
 
* 본문 캡춰
2021-02-18 오전 7-18-14.jpg

 

번호 제목 글쓴이 날짜 조회 수
246 [Gemini] ajax 와 fetch 의 차이 황제낙엽 2025.01.04 3419
245 [검토 완료] 디바이스 카메라로 촬영한 사진을 서버에 업로드하기 샘플 황제낙엽 2024.11.21 3987
244 브라우저에서 이미지를 편집(crop 등) 할 수 있는 오픈소스 Cropper.js 황제낙엽 2024.11.16 3842
243 [ChatGPT] json data 의 정렬 [1] 황제낙엽 2024.07.23 3352
242 DOMContentLoaded 이벤트와 window.onload 이벤트 황제낙엽 2024.07.15 3669
241 fetch() 사용 예제들 황제낙엽 2024.07.09 3380
240 [Copilot] Vanilla JavaScript에서 외부 스크립트 파일에 정의된 함수들을 로드 황제낙엽 2024.06.21 3758
239 [Copilot] ES6 모듈(module) 문법 황제낙엽 2024.06.21 3805
238 [Copilot] JSON 객체 내부 데이터를 순회하면서 조회하는 코드 황제낙엽 2024.06.02 3270
237 [Copilot] JavaScript로 서버에 특정 값을 POST 방식으로 전달하고 응답을 기다리지 않고 바로 종료 황제낙엽 2024.05.31 3615
236 json 데이터 내의 변수명에 prefix 로 type 표현하기 황제낙엽 2024.04.15 3361
235 fetch() 함수 사용 예제 file 황제낙엽 2023.11.23 3605
234 현재 document 의 host 와 port 를 얻는 방법 황제낙엽 2023.10.03 4209
233 (Bard) FileReader 로 여러개의 파일을 read 하는 법 file 황제낙엽 2023.08.23 3660
232 How to build a file upload service with vanilla JavaScript file 황제낙엽 2023.08.22 3715
231 (Bard) JavaScript로 JSON 배열을 작성하는 방법 황제낙엽 2023.08.21 3672
230 모바일 브라우저에서 file input element 를 이용하여 여러장의 이미지를 서버에 전송하려 할때 [1] 황제낙엽 2023.08.21 3703
229 navigator.mediaDevices 황제낙엽 2023.08.21 3798
228 Barcode Detection API 황제낙엽 2023.08.06 3854
227 정규식을 이용한 이메일 검증 스크립트 file 황제낙엽 2023.06.25 2894