JavaScript 비동기 프로그래밍 및 콜백

컴퓨터는 asynchronous 설계되었습니다.

비동기는 기본 프로그램 흐름에서 일이 발생할 수 있음을 의미합니다independently.

현재 소비자 컴퓨터에서 모든 프로그램은 특정 시간 슬롯 동안 실행된 다음 다른 프로그램이 계속 실행되도록 실행을 중지합니다execution. 이것은 알아차릴 수 없을 정도로 빠르게 순환합니다. 우리는 컴퓨터가 동시에 많은 프로그램을 실행한다고 생각하지만 이것은 환상입니다(다중 프로세서 시스템 제외).

프로그램은 내부적으로 interrupts , 시스템의 주의를 끌기 위해 프로세서로 보내는 신호를 사용합니다.

나는 이것의 내부로 들어가지 않을 것이지만, 단지 프로그램이 비동기적이고 주의가 필요할 때까지 실행을 멈추는 것이 정상이라는 것을 명심하십시오. 프로그램이 네트워크의 응답을 기다리는 경우 요청이 완료될 때까지 프로세서를 중지할 수 없습니다.

일반적으로 프로그래밍 언어는 synchronous이며 일부는 언어 또는 라이브러리를 통해 관리하는 방법 asynchronicity을 제공합니다. C, Java, C#, PHP, Go, Ruby, Swift 및 Python은 기본적으로 모두 동기식입니다. 그들 중 일부는 스레드를 사용하여 비동기를 처리하여 새 프로세스를 생성합니다.

자바스크립트



JavaScript는 기본적으로 synchronous이고 single threaded 입니다. 이는 코드가 새 스레드를 생성하고 병렬로 실행할 수 없음을 의미합니다.

코드 라인은 차례로 실행되며 이러한 유형의 실행 흐름을 Blocking Code/Mode 라고도 합니다.

차단 코드 예



다음 내용으로 input.txt라는 텍스트 파일을 만듭니다.

전체 파일을 읽을 때까지 다른 행은 실행되지 않습니다.

다음 코드를 사용하여 app.js라는 js 파일을 만듭니다.

var fs = require("fs");

var data = fs.readFileSync('input.txt');

console.log(data.toString());

console.log("Program Ended");


이제 main.js를 실행하여 결과를 확인하십시오.

node main.js


산출:

No other lines will execute until the whole file is read.

Program Ended


여기에서 우리는 라인의 코드가 차례로 실행되는 것을 명확하게 볼 수 있습니다.

그러나 JavaScript는 born browser 내부에 있었고, 초기에 주요 작업은 onClick , onMouseOver , onChange , onSubmit 등과 같은 사용자 작업에 응답하는 것이었습니다. 동기 프로그래밍 모델로 어떻게 이것을 할 수 있습니까?

답은 환경에 있었습니다. 브라우저는 이러한 종류의 기능을 처리할 수 있는 API 세트를 제공하여 이를 수행하는 방법을 제공합니다.

보다 최근에 Node.js는 이 개념을 파일 액세스, 네트워크 호출 등으로 확장하기 위해 non-blocking I/O environment를 도입했습니다.

콜백



사용자가 언제 버튼을 클릭할지 알 수 없습니다. 따라서 클릭 이벤트에 대한 이벤트 핸들러를 정의합니다. 이 이벤트 핸들러는 이벤트가 트리거될 때 호출되는 함수를 허용합니다.

document.getElementById('button').addEventListener('click', () => {

  //item clicked

})


이것은 소위 callback 입니다.
A callback is a simple function that's passed as a value to another function, and will only be executed when the event happens. We can do this because JavaScript has first-class functions, which can be assigned to variables and passed around to other functions (called higher-order functions)
페이지가 준비되었을 때만 콜백 함수를 실행하는 창 객체의 로드 이벤트 리스너에서 모든 클라이언트 코드를 래핑하는 것이 일반적입니다.

window.addEventListener('load', () => {

  //window loaded

  //do what you want

})


콜백은 DOM 이벤트뿐만 아니라 모든 곳에서 사용됩니다.

한 가지 일반적인 예는 타이머를 사용하는 것입니다.

setTimeout(() => {

  // runs after 2 seconds

}, 2000)


콜백에서 오류 처리



콜백 오류를 어떻게 처리합니까? 매우 일반적인 전략 중 하나는 Node.js가 채택한 것을 사용하는 것입니다. 모든 콜백 함수의 첫 번째 매개변수는 error 객체입니다. error-first callbacks

오류가 없으면 개체는 null 입니다. 오류가 있는 경우 오류에 대한 일부 설명 및 기타 정보가 포함됩니다.

fs.readFile('/file.json', (err, data) => {

  if (err !== null) {

    //handle error

    console.log(err)

    return

  }

  //no errors, process data

  console.log(data)

})


콜백 문제


Callbacks 심플한 케이스에 딱!

그러나 모든 콜백은 중첩 수준을 추가하고 많은 콜백이 있는 경우 코드가 매우 빠르게 복잡해지기 시작합니다.

window.addEventListener('load', () => {

  document.getElementById('button').addEventListener('click', () => {

    setTimeout(() => {

      items.forEach(item => {

        //your code here

      })

    }, 2000)

  })

})


이것은 단순한 4단계 코드이지만 훨씬 더 많은 수준의 중첩을 보았고 재미가 없습니다. 이러한 콜백 중첩을 JS 세계에서 Call-back Hell 문제라고 합니다.

어떻게 해결합니까?



콜백에 대한 대안

ES6부터 JavaScript는 콜백을 사용하지 않는 비동기 코드에 도움이 되는 몇 가지 기능을 도입했습니다. Promises (ES6)Async/Await (ES2017).
기사를 읽어주셔서 감사합니다. 이 기사를 통해 새로운 것을 배울 수 있기를 바랍니다. :)

좋은 웹페이지 즐겨찾기