>웹 프론트엔드 >JS 튜토리얼 >js 비동기 콜백 Async/Await와 Promise의 차이점, Async/Await가 Promise를 대체하는 6가지 이유

js 비동기 콜백 Async/Await와 Promise의 차이점, Async/Await가 Promise를 대체하는 6가지 이유

青灯夜游
青灯夜游원래의
2018-09-12 16:45:321602검색

이 장에서는 js 비동기 콜백 Async/Await와 Promise의 차이점과 Async/Await가 Promise를 대체하는 6가지 이유를 소개합니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

Async/Await란 무엇인가요?

async/await는 비동기 코드를 작성하는 새로운 방법입니다. 이전 메서드는 콜백 함수와 Promise였습니다.

async/await는 Promise를 기반으로 구현되어 일반 콜백 함수에는 사용할 수 없습니다.

async/await는 Promise와 마찬가지로 비차단입니다.

async/await는 비동기 코드를 동기 코드처럼 보이게 하는데, 바로 여기에 마법이 있습니다.

Async/Await 구문

예제에서 getJSON 함수는 약속이 성공적으로 해결되면 JSON 개체를 반환하는 약속을 반환합니다. 우리는 이 함수를 호출하고, 반환된 JSON 객체를 인쇄하고 "완료"를 반환합니다.

Promise 사용은 다음과 같습니다.

const makeRequest = () =>
  getJSON()
    .then(data => {
      console.log(data)
      return "done"
    })makeRequest()

Async/Await 사용은 다음과 같습니다.

const makeRequest = async () => {
  console.log(await getJSON())
  return "done"}makeRequest()

약간의 차이점이 있습니다.

함수 앞에 추가 aync 키워드가 있습니다. Await 키워드는 aync로 정의된 함수 내에서만 사용할 수 있습니다. 비동기 함수는 암시적으로 약속을 반환하며 약속의 확인 값은 함수 반환 값입니다. (예제에서 reosolve 값은 "done" 문자열입니다.)

포인트 1은 비동기 함수 내에 있지 않기 때문에 가장 바깥쪽 코드에서 Wait를 사용할 수 없음을 의미합니다.

// 不能在最外层代码中使用
awaitawait makeRequest()
// 这是会出事情的 
makeRequest().then((result) => {
  // 代码
 })

await getJSON()은 getJSON 약속이 실행되기 전에 성공적으로 해결될 때까지 console.log가 대기한다는 의미입니다.

왜 Async/Await가 더 나은가요?

1. 단순성

예에서 볼 수 있듯이 Async/Await를 사용하면 많은 코드가 절약됩니다. 그러면 Promise의 확인 값을 처리하기 위해 익명 함수를 작성할 필요가 없고 중복된 데이터 변수를 정의할 필요가 없으며 중첩된 코드를 피할 수 있습니다. 이러한 작은 이점은 빠르게 추가되며, 다음 코드 예제에서 더욱 분명해집니다.

2. 오류 처리

Async/Await를 사용하면 try/catch를 통해 동기 및 비동기 오류를 모두 처리할 수 있습니다. 아래 Promise 예제에서 try/catch는 Promise 내부에 있기 때문에 JSON.parse 오류를 처리할 수 없습니다. 오류 처리 코드가 매우 중복되도록 .catch를 사용해야 합니다. 더욱이 실제 생산 코드는 더 복잡해질 것입니다.

const makeRequest = () => {
  try {
    getJSON()
      .then(result => {
        // JSON.parse可能会出错
        const data = JSON.parse(result)
        console.log(data)
      })
      // 取消注释,处理异步代码的错误
      // .catch((err) => {
      //   console.log(err)
      // })
  } catch (err) {
    console.log(err)
  }}

aync/await를 사용하면 catch가 JSON.parse 오류를 처리할 수 있습니다.

const makeRequest = async () => {
  try {
    // this parse may fail
    const data = JSON.parse(await getJSON())
    console.log(data)
  } catch (err) {
    console.log(err)
  }}

3. 조건문

다음 예에서는 데이터를 얻은 다음 직접 반환할지 아니면 계속해서 더 얻을지 결정해야 합니다. 반환된 데이터를 기반으로 한 데이터입니다. ·

const makeRequest = () => {
  return getJSON()
    .then(data => {
      if (data.needsAnotherRequest) {
        return makeAnotherRequest(data)
          .then(moreData => {
            console.log(moreData)
            return moreData          })
      } else {
        console.log(data)
        return data      }
    })}

보기만 해도 머리가 아픈 코드들입니다. 최종 결과를 가장 바깥쪽 Promise에 전달하기만 하면 되는 중첩(6개 수준), 괄호 및 return 문과 혼동되기 쉽습니다.

async/await를 사용하여 위의 코드를 작성하면 가독성이 크게 향상될 수 있습니다.

const makeRequest = async () => {
  const data = await getJSON()
  if (data.needsAnotherRequest) {
    const moreData = await makeAnotherRequest(data);
    console.log(moreData)
    return moreData  } else {
    console.log(data)
    return data    
  }}

4. 중간 값

아마도 promise1을 호출하고 promise1에서 반환된 결과를 사용하여 promise2를 호출한 다음 그 결과를 사용하는 시나리오를 접했을 것입니다. 둘 다 promise3을 호출합니다. 코드는 다음과 같을 것입니다:

const makeRequest = () => {
  return promise1()
    .then(value1 => {
      return promise2(value1)
        .then(value2 => {        
          return promise3(value1, value2)
        })
    })}

promise3에 value1이 필요하지 않으면 간단히 promise를 중첩할 수 있습니다. 중첩을 참을 수 없다면 Promise.all에 값 1과 2를 넣어 깊은 중첩을 피할 수 있습니다.

const makeRequest = () => {
  return promise1()
    .then(value1 => {
      return Promise.all([value1, promise2(value1)])
    })
    .then(([value1, value2]) => {      
      return promise3(value1, value2)
    })}

이 접근 방식은 가독성을 위해 의미론을 희생합니다. 중첩을 방지하는 것 외에는 value1과 value2를 배열에 넣을 이유가 없습니다.

async/await를 사용하면 코드가 매우 간단하고 직관적이 됩니다.

const makeRequest = async () => {
  const value1 = await promise1()
  const value2 = await promise2(value1)
  return promise3(value1, value2)}

5. 오류 스택

아래 예에서는 Promise 체인 어딘가에 오류가 발생했다고 가정하여 여러 Promise가 호출됩니다.

const makeRequest = () => {
  return callAPromise()
    .then(() => callAPromise())
    .then(() => callAPromise())
    .then(() => callAPromise())
    .then(() => callAPromise())
    .then(() => {
      throw new Error("oops");
    })}makeRequest()
  .catch(err => {
    console.log(err);
    // output
    // Error: oops at callAPromise.then.then.then.then.then (index.js:8:13)
  })

Promise 체인에 반환된 오류 스택은 오류가 발생한 위치에 대한 단서를 제공하지 않습니다. . 더 심각한 것은 오류 스택에 있는 유일한 함수인 callAPromise가 오류와 관련이 없다는 점입니다. (파일 이름과 줄 번호는 여전히 유용합니다).

그러나 async/await의 오류 스택은 오류가 있는 함수를 가리킵니다.

const makeRequest = async () => {
  await callAPromise()
  await callAPromise()
  await callAPromise()
  await callAPromise()
  await callAPromise()
  throw new Error("oops");}makeRequest()
  .catch(err => {
    console.log(err);
    // output
    // Error: oops at makeRequest (index.js:7:9)
  })

개발 환경에서는 이러한 이점이 크지 않습니다. 하지만 프로덕션 환경의 오류 로그를 분석할 때 매우 유용할 것입니다. 이때, then 체인에서 오류가 발생했다는 사실을 아는 것보다 makeRequest에서 오류가 발생했다는 사실을 아는 것이 더 좋습니다.

6. 디버깅

마지막이자 가장 중요한 점은 async/await를 사용하면 코드 디버깅이 더 쉬워진다는 것입니다. Promise 디버깅이 어려운 2가지 이유:

1) 표현식을 반환하는 화살표 함수에는 중단점을 설정할 수 없습니다.

js 비동기 콜백 Async/Await와 Promise의 차이점, Async/Await가 Promise를 대체하는 6가지 이유

2) .then 코드 블록에 중단점을 설정하는 경우 Step Over 단축키를 사용하면 디버거가 비동기 코드를 건너뛰기 때문에 다음 .then으로 점프하지 마세요.

await/async를 사용하면 더 이상 많은 화살표 함수가 필요하지 않으므로 동기 코드를 디버깅하는 것처럼 wait 문을 건너뛸 수 있습니다.

js 비동기 콜백 Async/Await와 Promise의 차이점, Async/Await가 Promise를 대체하는 6가지 이유

Conclusion

Async/Await는 최근 몇 년간 JavaScript에 추가된 기능입니다. 가장 혁신적인 기능 중 하나입니다. Promise 구문이 얼마나 나쁜지 깨닫게 하고 직관적인 대안을 제공합니다.

걱정

Async/Await에 대해 합리적인 의심이 있을 수도 있습니다.
이는 비동기 코드를 덜 명확하게 만듭니다. 우리는 비동기 코드를 식별하기 위해 콜백 함수나 .then을 사용하는 데 익숙하며 새 플래그에 익숙해지는 데 몇 주가 걸릴 수 있습니다. 그러나 C#에는 수년 동안 이 기능이 있었으며 이 기능에 익숙한 친구들은 일시적인 불편함이 그만한 가치가 있다는 것을 알아야 합니다.
Node 7은 LTS(장기 지원 릴리스)가 아닙니다. 그러나 Node 8은 다음 달에 릴리스될 예정이므로 코드를 새 버전으로 마이그레이션하는 것은 매우 간단합니다.

위 내용은 js 비동기 콜백 Async/Await와 Promise의 차이점, Async/Await가 Promise를 대체하는 6가지 이유의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.