js에서 비동기/대기

비동기 프로그래밍은 프로그램이 잠재적으로 오래 실행되는 작업을 시작하고 해당 작업이 완료될 때까지 기다리지 않고 해당 작업이 실행되는 동안 다른 이벤트에 계속 응답할 수 있도록 하는 기술입니다. 해당 작업이 완료되면 프로그램에 결과가 표시됩니다.



참고: 이 자습서에서는 JavaScript를 사용하지만 동일한 원칙이 Python/C#과 같은 다른 언어에도 적용됩니다.

애초에 Async/Await가 필요한 이유는 무엇입니까?
Promise와 Async가 JavaScript에 도입되기 전에는 시간이 걸리고 메인 스레드를 차단하는 모든 작업으로 인해 콜백 지옥이 발생했습니다. 예를 들어 약 2초가 걸리는 API 요청을 해야 한다고 가정해 보겠습니다. 이것은 당신이 할 것입니다 :

const getResource = callback => {
    setTimeout(() => {
        callback('some resource');
    }, 2000);
}

getResource(resource => console.log(resource));


이 스니펫에서는 7행의 함수를 getResource 함수의 인수로 전달하고 2초 후에 요청된 정보로 함수를 호출합니다. 그렇게 나빠 보이지 않죠? 코드가 커짐에 따라 상황은 더욱 악화되고 다단계 중첩 콜백과 다음과 같은 결과가 나타납니다.

fs.readdir(source, function (err, files) {
  if (err) {
    console.log('Error finding files: ' + err)
  } else {
    files.forEach(function (filename, fileIndex) {
      console.log(filename)
      gm(source + filename).size(function (err, values) {
        if (err) {
          console.log('Error identifying file size: ' + err)
        } else {
          console.log(filename + ' : ' + values)
          aspect = (values.width / values.height)
          widths.forEach(function (width, widthIndex) {
            height = Math.round(width / aspect)
            console.log('resizing ' + filename + 'to ' + height + 'x' + height)
            this.resize(width, height).write(dest + 'w' + width + '_' + filename, function(err) {
              if (err) console.log('Error writing file: ' + err)
            })
          }.bind(this))
        }
      })
    })
  }
})


이 코드는 읽기, 유지 관리 및 확장하기가 더 어려워집니다. 콜백 지옥에 대해 더 알고 싶다면 여기를 방문하세요.

약속
콜백 지옥을 수정하기 위해 Promise가 ES2015에 도입되었습니다. 그들의 목표는 코드를 단순화하고 가독성을 개선하며 JS에 더 많은 비동기 기능을 추가하는 것이었습니다. 약속을 사용하면 첫 번째 예의 코드는 다음과 같습니다.

const getResource = new Promise((resolve, reject) => {
    setTimeout(() => resolve('some resource'), 2000);
});

getResource.then(resource => console.log(resource));


1행에서 Promise 객체를 생성합니다. resolve 및 reject 함수를 받는 인수로 함수를 전달합니다. 그 안에서 우리는 API를 호출하고 원하는 콘텐츠로 Promise를 해결합니다. 오류가 발생하면 의미 있는 오류 메시지와 함께 Promise를 거부합니다. 그런 다음 .then()에 콜백 함수를 전달하여 이 약속을 호출합니다. 오류를 처리하기 위해 .catch()에 콜백 함수도 전달합니다.

이것은 확실히 한 단계 발전된 것이지만 완전한 해결책은 아닙니다. 우리는 여전히 콜백 함수, 체이닝 및 많은 중복 코드를 가지고 있습니다. 기술을 사용하여 피할 수 있지만 약속 지옥과 같은 것도 있습니다.

비동기/대기
비동기 기능은 ES2017에 도입되었으며 이제 IE를 제외한 모든 브라우저 사양과 호환됩니다. Async 함수는 Promise를 반환하는 함수입니다. 즉, 대기해야 합니다. 이전 버전과 호환되므로 레거시 대기로 작성된 모든 약속과 함께 대기를 계속 사용할 수 있습니다. 프라미스가 포함된 예시를 살펴보세요.

const getResource = () => new Promise((resolve, reject) => {
    setTimeout(() => resolve('some resource'), 2000);
});

main = async () => {
    const resource1 = await getResource();
    const resource2 = await getResource();
    console.log(resource1, resource2);
}

main();


이 예제는 조금 더 길지만 이것으로 혼동하지 마십시오. 비동기 함수는 거의 항상 코드 라인 측면에서 승리합니다. 여기서 우리는 먼저 약속을 정의하고 약간 다르다는 점에 주목합니다. 이제 약속을 반환하는 함수입니다. 동일한 약속을 두 번 사용할 수 있는 방법을 보여주기 위해 했습니다. 나중에 우리는 async 함수에서 await 키워드만 사용할 수 있기 때문에 async 함수 main을 정의합니다. 그런 다음 대기를 사용하여 약속에서 리소스를 가져옵니다. 이것은 기본 스레드와 UI 스레드를 차단하지 않으므로 async라는 단어가 사용됩니다. 이제 콜백이 적고 오류를 처리하려면 다른 언어와 마찬가지로 await 문을 try/catch/finally 블록으로 래핑해야 합니다. 따라서 가독성과 단순성 측면에서 승리는 분명합니다. 비동기 코드는 콜백/약속과 달리 일반 동기 코드처럼 보입니다.

원래 게시 위치: https://www.codedolt.com/blog/2022-09-30-async-await-in-js/

좋은 웹페이지 즐겨찾기