일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Topics
- lda
- (깃)git bash
- Python
- 네이버뉴스
- java
- RESFUL
- 토픽추출
- 코사인 유사도
- spring MVC(모델2)방식
- 파이썬
- db
- test
- 크롤링
- word2vec
- r
- 자바
- Websocket
- tomoto
- pytorch
- 지마켓
- 게시판 만들기
- 幼稚园杀手(유치원킬러)
- jsp 파일 설정
- mysql
- Gmarket
- 이력서
- 방식으로 텍스트
- oracle
- 과학백과사전
- Today
- Total
무회blog
일반적인 비동기 프로그래밍 개념 본문
비동기?
일반적으로 주어진 프로그램의 코드는 한 번에 하나의 일만 발생하면서 바로 실행됩니다. 함수가 다른 함수의 결과에 의존하는 경우 다른 함수가 완료되어 리턴 될 때까지 기다려야하며, 그 때까지 전체 프로그램은 본질적으로 사용자 관점에서 중지됩니다.
예를 들어, Mac 사용자는 때때로 회전하는 무지개 색 커서 (또는 "비치 볼"이라고도 함)로 이것을 경험합니다. 이 커서는 운영 체제에서 "사용중인 현재 프로그램을 중지하고 무언가가 완료 될 때까지 기다려야하는데 시간이 너무 오래 걸리므로 무슨 일이 일어나고 있는지 궁금 할 것입니다."
이것은 실망스러운 경험이며 컴퓨터 처리 능력을 잘 사용하지 못합니다. 특히 컴퓨터에 여러 개의 프로세서 코어가있는 시대에는 더욱 그렇습니다. 다른 작업이 다른 프로세서 코어에서 작동하도록하고 언제 완료되었는지 알려 주면 무언가를 기다리는 것이 의미가 없습니다. 이를 통해 비동기 프로그래밍 의 기초가되는 다른 작업을 수행 할 수 있습니다 . 이러한 작업을 비동기 적으로 실행할 수있는 API를 제공하는 것은 사용중인 프로그래밍 환경 (웹 개발의 경우 웹 브라우저)에 달려 있습니다.
차단 코드
비동기 기술은 특히 웹 프로그래밍에서 매우 유용합니다. 웹 응용 프로그램이 브라우저에서 실행되고 브라우저로 제어를 반환하지 않고 집중적 인 코드 덩어리를 실행하면 브라우저가 정지 된 것처럼 보일 수 있습니다. 이것을 차단 이라고합니다 . 웹 앱이 프로세서 제어를 반환 할 때까지 브라우저는 사용자 입력을 계속 처리하고 다른 작업을 수행 할 수 없습니다.
차단이라는 의미를 보여주는 몇 가지 예를 살펴 보겠습니다.
우리에서 간단한 sync.html의 예 ( 이 라이브 실행을 참조하십시오 , 우리는 클릭 할 때 너무 버튼에 클릭 이벤트 리스너를 추가), 그것은 시간이 많이 걸리는 작업을 실행 (계산 천만 날짜는 콘솔에 마지막 하나를 기록) DOM에 단락을 추가합니다.
const btn = document.querySelector('button'); btn.addEventListener('click', () => { let myDate; for(let i = 0; i < 10000000; i++) { let date = new Date(); myDate = date } console.log(myDate); let pElem = document.createElement('p'); pElem.textContent = 'This is a newly-added paragraph.'; document.body.appendChild(pElem); });
예제를 실행할 때 JavaScript 콘솔을 연 다음 버튼을 클릭하면 날짜 계산이 완료되고 콘솔 메시지가 기록 될 때까지 단락이 표시되지 않습니다. 코드는 소스에 표시된 순서대로 실행되며, 이전 작업이 완료 될 때까지 이후 작업이 실행되지 않습니다.
참고 : 이전 예제는 매우 비현실적입니다. 실제 웹 앱에서 천만 날짜를 계산하지 않을 것입니다! 그러나 기본 아이디어를 제공하는 역할을합니다.
우리의 두 번째 예에서는 간단한 동기화-UI-blocking.html ( 가 살고 참조 ), 우리는 당신이 진짜 페이지에 걸쳐 올 수도 있다는 약간 더 현실적인 뭔가를 시뮬레이션 할 수 있습니다. UI 렌더링과의 사용자 상호 작용을 차단합니다. 이 예제에는 두 개의 버튼이 있습니다.
- 클릭하면 사용 가능한 <canvas>백만 개의 파란색 원으로 채워지는 "캔버스 채우기"단추 .
- 클릭하면 경고 메시지가 표시되는 "경고를 위해 클릭하십시오"단추.
function expensiveOperation() { for(let i = 0; i < 1000000; i++) { ctx.fillStyle = 'rgba(0,0,255, 0.2)'; ctx.beginPath(); ctx.arc(random(0, canvas.width), random(0, canvas.height), 10, degToRad(0), degToRad(360), false); ctx.fill() } } fillBtn.addEventListener('click', expensiveOperation); alertBtn.addEventListener('click', () => alert('You clicked me!') );
첫 번째 단추를 클릭 한 다음 두 번째 단추를 빠르게 클릭하면 원 렌더링이 완료 될 때까지 경고가 표시되지 않습니다. 첫 번째 작업은 실행이 끝날 때까지 두 번째 작업을 차단합니다.
참고 : 좋습니다. 우리의 경우에는 추악하고 차단 효과를 속이고 있지만 이것은 실제 앱 개발자가 항상 완화하기 위해 싸우는 일반적인 문제입니다.
왜 이런거야? 대답은 일반적으로 말해서 JavaScript가 단일 스레드 이기 때문 입니다. 이 시점에서 스레드 개념을 소개해야 합니다 .
실
스레드는 기본적으로 프로그램이 작업을 완료하는 데 사용할 수있는 하나의 과정이다. 각 스레드는 한 번에 하나의 작업 만 수행 할 수 있습니다.
Task A --> Task B --> Task C
각 작업은 순차적으로 실행됩니다. 다음 작업을 시작하기 전에 작업을 완료해야합니다.
앞에서 언급했듯이 많은 컴퓨터에는 이제 여러 개의 코어가 있으므로 한 번에 여러 작업을 수행 할 수 있습니다. 여러 스레드를 지원할 수있는 프로그래밍 언어는 여러 코어를 사용하여 여러 작업을 동시에 완료 할 수 있습니다.
Thread 1: Task A --> Task B Thread 2: Task C --> Task D
자바 스크립트는 단일 스레드입니다
JavaScript는 전통적으로 단일 스레드입니다. 코어가 여러 개인 경우에도 메인 스레드 라는 단일 스레드에서만 작업을 실행할 수 있습니다. 위의 예제는 다음과 같이 실행됩니다.
Main thread: Render circles to canvas --> Display alert()
얼마 후, JavaScript는 그러한 문제를 해결하는 데 도움이되는 몇 가지 도구를 얻었습니다. 웹 워커를 사용하면 JavaScript 처리 중 일부를 워커라고하는 별도의 스레드로 보낼 수 있으므로 여러 JavaScript 청크를 동시에 실행할 수 있습니다. 일반적으로 작업자를 사용하여 주 스레드에서 값 비싼 프로세스를 실행하여 사용자 상호 작용이 차단되지 않도록합니다.
Main thread: Task A --> Task C Worker thread: Expensive task B
이를 염두에두고 브라우저의 JavaScript 콘솔을 다시 연 상태 에서 simple-sync-worker.html ( 실시간으로 실행 참조)을 살펴보십시오 . 이것은 별도의 작업자 스레드에서 천만 날짜를 계산하는 이전 예제를 다시 작성한 것입니다. 이제 버튼을 클릭하면 날짜 계산이 끝나기 전에 브라우저가 단락을 표시 할 수 있습니다. 첫 번째 작업은 더 이상 두 번째 작업을 차단하지 않습니다.
비동기 코드
웹 워커는 매우 유용하지만 한계가 있습니다. 중요한 것은 DOM 에 액세스 할 수 없다는 것입니다. 작업자가 UI를 업데이트하기 위해 직접 작업을 수행하도록 할 수는 없습니다. 작업자 내부에 백만 개의 파란색 원을 렌더링 할 수 없었습니다. 기본적으로 숫자 처리 만 할 수 있습니다.
두 번째 문제는 작업자에서 실행되는 코드가 차단되지 않지만 여전히 기본적으로 동기화된다는 것입니다. 함수가 여러 이전 프로세스의 결과에 의존 할 때 문제가됩니다. 다음 스레드 다이어그램을 고려하십시오.
Main thread: Task A --> Task B
이 경우 작업 A가 서버에서 이미지를 가져 오는 것과 같은 작업을하고 작업 B가 필터를 적용하는 것과 같은 작업을 이미지에서 수행한다고 가정 해 보겠습니다. 작업 A 실행을 시작한 다음 즉시 작업 B를 실행하려고하면 이미지를 아직 사용할 수 없으므로 오류가 발생합니다.
Main thread: Task A --> Task B --> |Task D| Worker thread: Task C -----------> | |
이 경우 작업 D가 작업 B와 작업 C의 결과를 모두 사용한다고 가정 해 봅시다. 이러한 결과를 동시에 사용할 수 있다고 보장 할 수 있다면 문제가되지는 않지만 그럴 가능성은 없습니다. 입력 중 하나를 아직 사용할 수 없을 때 작업 D가 실행을 시도하면 오류가 발생합니다.
이러한 문제를 해결하기 위해 브라우저를 통해 특정 작업을 비동기 적으로 실행할 수 있습니다. Promises 와 같은 기능 을 사용하면 작업 실행 (예 : 서버에서 이미지 가져 오기)을 설정 한 다음 다른 작업을 실행하기 전에 결과가 반환 될 때까지 기다릴 수 있습니다.
Main thread: Task A Task B Promise: |__async operation__|
작업이 다른 곳에서 발생하므로 비동기 작업이 처리되는 동안 주 스레드가 차단되지 않습니다.
다음 기사에서 비동기 코드를 작성하는 방법을 살펴 보겠습니다. 신나는 물건? 계속 읽으세요!
결론
현대적인 소프트웨어 설계는 프로그램이 한 번에 하나 이상의 작업을 수행 할 수 있도록 비동기식 프로그래밍을 사용하는 것에 따라 점점 더 발전하고 있습니다. 새롭고 더 강력한 API를 사용함에 따라 작업을 수행하는 유일한 방법이 비동기 적으로 수행되는 경우가 더 많습니다. 비동기 코드를 작성하기가 어려웠습니다. 여전히 익숙해 지지만 훨씬 쉬워졌습니다. 이 모듈의 나머지 부분에서는 비동기 코드가 중요한 이유와 위에서 설명한 일부 문제를 피하는 코드를 디자인하는 방법에 대해 자세히 설명합니다.
출처:
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Concepts
'js' 카테고리의 다른 글
html 요소 좌표,(상대좌표, 절대좌표) 값 구하기 ,getBoundingClientRect (0) | 2022.06.22 |
---|---|
codeLink _001 (0) | 2020.04.14 |