코딩하는 김딸기

05-1. JavaScript 비동기 본문

자바스크립트/Likelion_JS

05-1. JavaScript 비동기

김딸기* 2024. 10. 5. 17:34

Web API

API(Application Programming Interface) 를 한마디로 정리하면 프로그래밍 언어로 만들어진 데이터와 기능의 모음입니다. • 어떤 기능을 구현할 때 “유튜브 API 를 이용해서” 혹은 “카카오 API 를 이용해서” 구현했다는 용어를 많이씁니다.

• 이 의미는 유튜브 혹은 카카오와 애플리케이션에서 연동할 때 연동방법을 추상화 시켜서 제공하는 API 를사용한다는 의미입니다.

• API 는 변수, 함수 혹은 클래스로 제공됩니다.

 

• Browser APIs : 브라우저에 내장되어 있는 API

• Third-Party APIs : 다른 벤더 혹은 플랫폼에서 제공하는 API


호출 스케줄링

함수 호출을 미리 예약할 때 사용하는 두 가지 방법이 있습니다. 이걸 “호출 스케줄링”이라고 해요.

1. setTimeout()

  • 정의: 일정 시간이 지난 후에 함수를 한 번 실행합니다.
  • 사용 예: "1초 후에 이 함수를 실행해줘!"라는 식으로 사용할 수 있어요.
  • 취소하기: 만약 예약한 함수를 취소하고 싶다면 clearTimeout()을 사용합니다.

2. setInterval()

  • 정의: 일정한 시간 간격으로 함수를 반복해서 실행합니다.
  • 사용 예: "1초마다 이 함수를 계속 실행해줘!"라고 말하는 것과 같아요.
  • 취소하기: clearInterval()을 사용하면 예약된 반복 호출을 취소할 수 있습니다.

중요한 점

  • setInterval()에서의 시간: 설정한 시간은 함수가 호출되는 주기를 의미합니다. 예를 들어, 1초 주기로 설정하면 매 1초마다 함수가 실행되는데, 만약 함수가 실행되는 데 0.5초가 걸린다면 다음 호출은 1초 후가 아니라 0.5초 후에 이루어져요.

Promise

프라미스(Promise)는 JavaScript에서 비동기 작업을 처리하는 방법입니다.

  • then(): 비동기 작업이 성공적으로 완료되었을 때 실행할 콜백 함수를 등록합니다. 주로 작업의 결과를 받을 때 사용합니다.
  • catch(): 비동기 작업이 실패했을 때 실행할 콜백 함수를 등록합니다. 주로 에러 처리를 할 때 사용합니다.
  • finally(): 비동기 작업이 성공하든 실패하든 상관없이 마지막에 실행할 코드를 등록합니다. 주로 정리 작업이나 상태를 업데이트할 때 사용합니다.

이렇게 프라미스는 작업의 성공과 실패를 처리할 수 있는 방법을 제공합니다.


 

async와 await

async와 await는 JavaScript에서 비동기 코드를 더 간결하고 쉽게 작성할 수 있도록 도와주는 문법입니다. 이 두 가지를 간단하게 설명하자면 다음과 같습니다.

async

  • async함수를 선언할 때 사용하는 키워드입니다.
  • async로 선언된 함수는 항상 Promise를 반환합니다. 즉, 비동기 작업을 수행하는 함수라고 생각하면 됩니다.
  • 이 함수 안에서 데이터를 반환하려면 return 키워드를 사용합니다.

await

  • await는 async 함수 내에서만 사용할 수 있는 키워드입니다.
  • await는 "기다리다"라는 뜻을 가지고 있습니다. await가 붙은 부분의 코드가 실행될 때까지 async 함수가 멈추고 기다립니다.
  • 즉, 비동기 작업이 완료될 때까지 다음 코드가 실행되지 않도록 합니다.

 


-비동기 함수(async function)와 일반적인 비동기 작업(setTimeout)을 사용하여 콘솔에 메시지를 출력하는 예제

//test1-async로 함수선언
//비동기적으로 실행될 함수-호출한 곳이 대기하지 않도록 하는 함수
async function  myFun1() {
    setTimeout(()=>console.log('myFun1 call'),2000)
   
}
let  myFun2=async()=> {
    setTimeout(()=>console.log('myFun2 call'),1000)
   
}
console.log('step1')
myFun1()
console.log('step2')
myFun2()
console.log('step3')
  1. 함수 선언:
    • myFun1이라는 비동기 함수를 정의합니다. 이 함수는 2초 후에 'myFun1 call'이라는 메시지를 콘솔에 출력합니다.
    • setTimeout특정 시간(여기서는 2000ms, 즉 2초) 후에 주어진 함수를 실행하는 메서드입니다.
  2. 화살표 함수 선언:
    • myFun2라는 비동기 화살표 함수를 정의합니다. 이 함수는 1초 후에 'myFun2 call'이라는 메시지를 콘솔에 출력합니다.
    • 이 역시 setTimeout을 사용하여 일정 시간 후에 실행됩니다.
  3. 콘솔 출력:
    • 첫 번째로 'step1'을 콘솔에 출력합니다.
    • 그 다음, myFun1()을 호출하지만 이 함수는 비동기적으로 실행되므로 호출한 위치는 대기하지 않고 계속 실행됩니다.
    • 'step2'를 콘솔에 출력합니다.
    • 다음으로 myFun2()를 호출합니다. 이 함수도 비동기적으로 실행되므로 다시 대기하지 않고 계속 실행됩니다.
    • 마지막으로 'step3'를 콘솔에 출력합니다.

최종 콘솔 출력 순서

이 코드를 실행하면 다음과 같은 순서로 콘솔에 출력됩니다:

  1. 'step1'
  2. 'step2'
  3. 'step3'
  4. 1초 후: 'myFun2 call'
  5. 2초 후: 'myFun1 call'

요약

  • 이 코드는 비동기 함수와 setTimeout을 사용하여 지연된 작업을 처리하는 방법을 보여줍니다. 비동기 함수(async)는 호출 후 즉시 다음 코드를 실행할 수 있게 하며, 주어진 시간 후에 메시지를 출력하는 지연 작업을 포함하고 있습니다.

 


 Promise async/await를 사용하여 값을 반환하고 출력하는 예제

//test2-promise vs async
function myFun3(){
    return new Promise((resolve,reject)=>{
        resolve(1)
    })
}
myFun3().then((value)=>console.log(value))//1

async function myFun4() {
    return 2//data 발생-내부적으로 promise의 resolve 활용
}
myFun4().then((value)=>console.log(value)) //2
  1. Promise를 사용한 함수:
    • myFun3 함수는 Promise 객체를 반환합니다.
    • Promise 생성자는 두 개의 인자(resolve와 reject)를 받아서, 이 함수가 성공적으로 완료되면 resolve(1)을 호출합니다. 즉, 이 Promise는 1이라는 값을 성공적으로 반환합니다.
     
    • myFun3()가 호출되면, 반환된 Promise에서 then 메서드를 사용하여 결과값(value)을 받아 콘솔에 출력합니다. 결과적으로 1이 출력됩니다.
  2. async/await을 사용한 함수:
    • myFun4 함수는 async 키워드로 정의된 비동기 함수입니다. 이 함수는 2를 반환합니다.
    • async 함수는 항상 Promise를 반환하며, 반환된 값(2)은 내부적으로 Promise.resolve(2)와 같습니다. 즉, 이 값은 Promise가 해결될 때 사용할 수 있는 값입니다.
     
    • myFun4()가 호출되면, 반환된 Promise에서 then 메서드를 사용하여 결과값(value)을 받아 콘솔에 출력합니다. 결과적으로 2가 출력됩니다.

최종 콘솔 출력

이 코드를 실행하면 다음과 같은 순서로 콘솔에 출력됩니다:

  1. 1 (myFun3의 결과)
  2. 2 (myFun4의 결과)

요약

  • Promiseasync/await는 비동기 작업을 처리하는 두 가지 방법입니다.
  • myFun3는 Promise를 직접 사용하여 값을 반환하고, myFun4는 async 함수로, 내부적으로 Promise를 사용하여 값을 반환합니다. 둘 다 최종적으로 then을 통해 결과값을 처리하여 콘솔에 출력됩니다.

비동기적으로 데이터를 반복적으로 가져오는 두 가지 방법을 보여줍니다: 하나는 Promise의 then() 메서드를 사용한 방법이고, 다른 하나는 async/await를 사용한 방법입니다.

//test3-promise 데이터 반복적으로 실행 획득
function getData(id){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>resolve(`${id} data`),1000)
    })
}
function myFun5(){
    getData(1)
        .then((value)=>{
            console.log(value)
            return getData(2)
        })
        .then((value)=>{
            console.log(value)
            return getData(3)
        })
        .then((value)=>{
            console.log(value)
           
        })
}
myFun5()


//then()으로 Promise를 이용하는 함수를 await로도 작성 가능
async function myFun6() {
    console.log(await getData(1))
    console.log(await getData(1))
    console.log(await getData(1))
}
myFun6()
 
  1. Promise를 사용한 데이터 반복 실행:
    • getData 함수는 주어진 id에 따라 데이터를 반환하는 Promise를 생성합니다.
    • 이 Promise는 1초 후에 ${id} data라는 문자열을 반환합니다.
     
    • myFun5 함수는 getData(1)을 호출하여 데이터를 가져옵니다. 이 데이터가 반환된 후, 첫 번째 then() 블록이 실행되고, '1 data'가 출력됩니다.
    • 이후 getData(2)를 호출하여 데이터를 가져오고, 두 번째 then() 블록에서 '2 data'가 출력됩니다.
    • 마지막으로 getData(3)을 호출하여 데이터를 가져오고, '3 data'가 출력됩니다.
    • 이 과정은 순차적으로 진행되며, 각 호출은 이전 호출이 완료된 후에 진행됩니다.
  2. async/await을 사용한 데이터 반복 실행:
    • myFun6는 async로 정의된 함수입니다.
    • 이 함수는 await 키워드를 사용하여 getData() 함수의 결과를 기다립니다.
    • 첫 번째 await getData(1)에서 '1 data'가 출력되고, 이후에 두 번째와 세 번째 호출을 통해 '2 data'와 '3 data'가 차례로 출력됩니다.
    • 이 경우에도 각 호출은 이전 호출이 완료된 후에 실행됩니다.
       

최종 콘솔 출력

이 두 코드를 실행하면 다음과 같은 순서로 콘솔에 출력됩니다:

  1. 1 data (1초 후)
  2. 2 data (1초 후)
  3. 3 data (1초 후)

myFun6에서의 출력도 동일하게 진행되며, 각 데이터 요청 후 1초의 지연이 발생합니다.

요약

  • **Promise와 then()**을 사용한 myFun5는 비동기 호출을 순차적으로 연결하여 결과를 처리합니다.
  • async/await을 사용한 myFun6은 코드의 가독성을 높여, 비동기 작업을 마치 동기 작업처럼 작성할 수 있게 합니다. 두 방법 모두 비동기적으로 데이터를 가져오고, 각 요청은 이전 요청이 완료된 후에 진행됩니다.
 
 

비동기적으로 여러 개의 함수를 동시에 실행하는 방법

  => myFun7과 myFun8 두 개의 비동기 함수에서 각각 다른 방식으로 데이터를 가져오는 방법

//test4-비동기적으로 실행시켜야 하는 여러개의 함수 동시진행
//모든 결과 데이터를 획득만 하면 된다
function funA(){
    return new PromiseI((resolve)=>{
        setTimeout(()=>{resolve(`funB data`)},1000)
    })
}

async function myFun7() {
    console.time()
    let aData=await funA()
    console.log(aData)
    let bData=await funB()
    console.log(bData)
    console.timeEnd()
}

//함수호출에 await가 아니라 결과 data에 await/ 함수는 동시진향
async function  myFun8() {
    console.time()
    let aData= funA()
    let bData= funB()
    console.log(await aData)
    console.log(await bData)
    console.timeEnd()

}
  1. 비동기 함수 funA:
    • funA 함수는 1초 후에 'funA data'를 반환하는 Promise를 생성합니다.
  2. 첫 번째 비동기 함수 myFun7:
    • myFun7은 await를 사용하여 funA와 funB의 결과를 순차적으로 기다립니다.
    • console.time()console.timeEnd()를 사용하여 전체 실행 시간을 측정합니다.
    • 이 함수는 funA와 funB의 결과를 순서대로 출력합니다.
  3. 두 번째 비동기 함수 myFun8:
    • myFun8은 funA()와 funB()를 비동기적으로 호출하지만 await를 사용하지 않아 결과를 즉시 기다리지 않습니다.
    • 두 함수가 거의 동시에 실행되며, 각각의 Promise가 완료되면 await를 통해 결과를 출력합니다.
    • 이 또한 console.time() console.timeEnd()로 전체 실행 시간을 측정합니다.

최종 콘솔 출력

  • 두 함수가 실행되면 결과는 다음과 같습니다:
    • myFun7은 순차적으로 실행되기 때문에 funA의 결과가 출력된 후 funB의 결과가 출력됩니다.
    • myFun8은 funA와 funB가 동시에 실행되기 때문에, 두 결과 모두 1초 후에 출력되지만, 두 결과는 거의 동시에 콘솔에 나타납니다.

요약

  • myFun7은 두 비동기 함수의 실행을 순차적으로 진행하여 한 함수의 결과를 기다린 후 다음 함수를 실행합니다.
  • myFun8은 두 비동기 함수를 동시에 실행하여 두 함수의 결과를 동시에 기다리며 출력합니다. 이로 인해 myFun8의 실행 시간이 짧아지는 효과가 있습니다.
  • 이 예제는 비동기 작업을 동시에 진행하는 방법을 보여줍니다. 각 함수는 독립적으로 실행되며, await는 결과를 가져오는 데만 사용됩니다.

 Promise.all()을 사용하여 여러 비동기 함수를 동시에 실행하고, 모든 함수의 결과를 한 번에 처리하는 방법

async function myFun9() {
    console.time()
    //비동기 함수를 여러개 호출, 동시진행하는 경우
    //all()을 이용할 수도
    //배열에 건 함수를 동시 실행시키며 모든 데이터가 획득된령우 콜백호출
    Promise.all([funA(),funB()]).then((value)=>{
        console.log(value)
        console.timeEnd()

    })
   
}
myFun9()
  1. 비동기 함수 myFun9:
    • myFun9 함수는 async로 정의되었지만, 내부에서는 Promise.all()을 사용하여 비동기 함수 funA()와 funB()를 동시에 실행합니다.
    • console.time()으로 실행 시간을 측정하고, 모든 Promise가 해결된 후 then() 블록이 실행됩니다.
    • Promise.all()은 전달된 배열의 모든 Promise가 해결될 때까지 기다리며,결과를 배열 형태로 반환합니다.
  2. Promise.all():
    • Promise.all()은 주어진 모든 Promise가 성공적으로 이행되면 그 결과를 배열로 반환합니다.
    • 만약 하나라도 실패하면, Promise.all()은 즉시 실패하고 해당 오류를 반환합니다.
  3. 결과 출력:
    • console.log(value)를 통해 funA()와 funB()의 결과를 배열로 출력합니다.
    • console.timeEnd()전체 실행 시간을 종료합니다.

최종 콘솔 출력

  • myFun9()를 호출하면, funA()와 funB()가 동시에 실행되므로 결과는 거의 동시에 출력됩니다.
  • 예를 들어, 각각의 함수가 1초 후에 결과를 반환한다면, 콘솔에는 다음과 같은 출력이 나타납니다:
    • [ 'funA data', 'funB data' ] (1초 후)

이 출력은 두 함수의 결과가 배열 형태로 나타나는 것을 보여줍니다.

요약

  • myFun9 함수는 Promise.all()을 사용하여 여러 비동기 작업을 동시에 실행하고, 모든 결과를 한 번에 처리합니다.
  • 이는 비동기 작업의 효율성을 높이며, 결과를 신속하게 처리할 수 있는 좋은 방법입니다.
  • Promise.all()을 사용하면 여러 비동기 작업의 결과를 쉽게 관리할 수 있습니다.
 
 

 

 

 

 

'자바스크립트 > Likelion_JS' 카테고리의 다른 글

05-3. Storage  (0) 2024.10.05
05-2. Ajax, Axios  (0) 2024.10.05
04-6. 클로저  (0) 2024.10.05
04-5. 클래스  (0) 2024.10.05
04-4. 다양한 OOP 기법  (0) 2024.10.05