JavaScript promise와 async await의 차이점은 무엇입니까?


97

내 응용 프로그램 (모바일 및 웹 모두)에서 이미 (Babel 덕분에) ECMAScript 6 및 ECMAScript 7 기능을 사용 하고 있습니다.

첫 번째 단계는 분명히 ECMAScript 6 레벨이었습니다. 나는 많은 비동기 패턴, 약속 (정말 유망한), 생성기 (* 기호가 왜 있는지 확실하지 않음) 등을 배웠습니다.이 중에서 약속은 제 목적에 꽤 잘 맞았습니다. 그리고 저는 그것들을 제 애플리케이션에서 꽤 많이 사용하고 있습니다.

다음은 기본 약속을 구현 한 방법에 대한 예제 / 의사 코드입니다.

var myPromise = new Promise(
    function (resolve,reject) {
      var x = MyDataStore(myObj);
      resolve(x);
    });

myPromise.then(
  function (x) {
    init(x);
});

시간이 경과, 나는 ECMAScript를 통해 7 개 기능, 그리고 그들 존재의 하나 온 ASYNCAWAIT키워드 / 기능. 이것들은 함께 놀라운 일을합니다. 내 약속 중 일부를 async & await. 프로그래밍 스타일에 큰 가치를 더하는 것 같습니다.

다시, 여기 내 async, await 함수가 어떻게 보이는지에 대한 의사 코드가 있습니다.

async function myAsyncFunction (myObj) {
    var x = new MyDataStore(myObj);
    return await x.init();
}
var returnVal = await myAsyncFunction(obj);

구문 오류 (있는 경우)를 제쳐두고 두 가지 모두 똑같은 작업을 수행합니다. 나는 거의 대부분의 약속을 비동기로 대체 할 수있었습니다.

promise가 비슷한 작업을 수행 할 때 async, await가 필요한 이유는 무엇입니까?

async, await가 더 큰 문제를 해결합니까? 아니면 지옥 콜백에 대한 다른 해결책 이었습니까?

앞서 말했듯이 약속과 비동기를 사용할 수 있으며 동일한 문제를 해결하기를 기다립니다. async await가 해결 한 특정 사항이 있습니까?

추가 참고 사항 :

저는 React 프로젝트와 Node.js 모듈에서 async, awaits 및 promise를 광범위하게 사용했습니다. React는 특히 초기 단계였으며 많은 ECMAScript 6 및 ECMAScript 7 기능을 채택했습니다.


3
첫 번째 코드 블록은 동기 작업에 대한 약속을 사용하는 것으로 보입니다. 왜 그렇게 하시겠습니까? 동기식은 본질적으로 코드를 작성하기가 더 쉽기 때문에 동기 작업을 약속으로 래핑하고 이제 비동기 상태로 만들 이유가 거의 없습니다.
jfriend00 dec.

@ jfriend00 네 맞아요. 코드를 수정했습니다. 감사.
bozzmob

2
지금도 두 코드 블록 모두에서 동기 함수와 함께 비동기 도구를 사용하려고합니다. 왜?
jfriend00

@ jfriend00 좋아요. 여기에 내 코드 gist.github.com/bozzmob/26d38b83dc37d1be37f5 있습니다. 내가 뭘 잘못하고 있는지 말해 주시겠습니까?
bozzmob

10
async 및 await가 무엇인지 이해하기 위해 많은 읽기를 수행해야하는 것처럼 들립니다. 여기에 몇 가지 기사는 다음과 같습니다 자바 스크립트에서 비동기 / 기다리고 긴 도로단순화 비동기 ES7 비동기 기능과 코딩ES7와 비동기 짐승을 길들이기 .
jfriend00

답변:


75

Promises가 비슷한 작업을 수행 할 때 async, await가 필요한 이유는 무엇입니까? async, await가 더 큰 문제를 해결합니까?

async/await단순히 비동기 코드에 동기식 느낌을줍니다. 그것은 매우 우아한 형태의 통 사적 설탕입니다.

간단한 쿼리 및 데이터 조작을 위해, 약속은 간단 할 수 있지만,이 복잡한 데이터 조작이고 이것 저것 포함 된 시나리오로 실행하면,이 코드는 단순히 경우에 무슨 일이 일어나고 있는지 이해하기 쉽게 보인다 는 동기 비록 (그것은 또 다른 방법 넣어로서, 구문 자체는 async/await주변을 둘러 볼 수있는 "부수적 복잡성"의 한 형태입니다 .

알고 싶다면 co같은 종류의 느낌을주기 위해 (제너레이터와 함께)와 같은 라이브러리를 사용할 수 있습니다 . 이와 같은 것들은 async/await궁극적으로 (기본적으로) 해결되는 문제를 해결하기 위해 개발되었습니다 .


"부수적 복잡성"이 무엇을 의미하는지 자세히 설명해 주시겠습니까? 또한 성능면에서 둘 사이에 차이가 없습니까?
bozzmob

@bozzmob, shaffner.us/cs/papers/tarpit.pdf <-그는 거기에서 "부수적 인 복잡성"을 설명합니다. 성능 문제에 관해서는 특히 V8 엔진이 무엇인지 의심합니다. 나는 거기에 약간의 성능 테스트가 있다고 확신하지만 그다지 걱정하지 않을 것입니다. 필요하지 않을 때 마이크로 최적화에 시간을 낭비하지 마십시오.
조쉬 빔

1
감사합니다! 이것은 제가 여러분으로부터 얻은 훌륭한 정보입니다. 그리고 예, 마이크로 최적화를 조사하지 않을 것입니다.
bozzmob 2015

나는이 설명이 도움이되었다고 nikgrozev.com/2015/07/14/...
mwojtera

33

Async / Await는 더 복잡한 시나리오에서 훨씬 더 좋은 구문을 제공합니다. 특히 루프 또는 try/ 와 같은 다른 특정 구조를 다루는 모든 것 catch.

예를 들면 :

while (!value) {
  const intermediate = await operation1();
  value = await operation2(intermediate);
}

이 예제는 Promise를 사용하는 것만으로도 상당히 복잡 할 것입니다.


이것은 같은 것을 이해하는 좋은 예입니다. 그렇다면 성능면에서 둘 사이에 차이가 없습니까? 그리고 코드에서 사용하는 것이 더 낫습니까? Async Await는 최소한 귀하의 예제를 본 후에 더 좋아 보입니다.
bozzmob

1
@bozzmob : 성능에는 차이가 없습니다. async / await를 사용하는 것이 편하다면 추천합니다. 실제로 공식 표준의 일부가 아니기 때문에 아직 직접 사용하지 않습니다.
Stephen Cleary

예, 표준의 일부가 아니라는 데 동의하지만 ReactJS (특별히 네이티브 반응)의 경우 코드의 일부에서 사용해야합니다. 그래서 그들 중 절반은 약속이고 절반은 비동기식입니다. 그래서 그 질문을했습니다. 필요한 정보에 감사드립니다.
bozzmob

1
아무도 그들의 코드 샘플에서 try / catch 블록을 사용하지 않을 때 많은 사람들이 혼란 스럽거나 오해하고 있다고 생각합니다.
Augie Gardner

그런 말인가요? const getValue = value => value || operation1().then(operation2).then(getValue);
Sharcoux

13

Promises가 비슷한 작업을 수행 할 때 async, await가 필요한 이유는 무엇입니까? async, await가 더 큰 문제를 해결합니까? 아니면 지옥 콜백에 대한 다른 해결책 이었습니까? 앞서 말했듯이 Promises와 Async, Await를 사용하여 동일한 문제를 해결할 수 있습니다. Async Await가 해결 한 특정 사항이 있습니까?

async/ await구문 을 이해해야 할 첫 번째 사항 은 약속을 늘리기위한 구문 설탕 일뿐입니다. 사실 async함수 의 반환 값은 약속입니다. async/ await구문은 동기식으로 비동기식으로 작성할 수있는 가능성을 제공합니다. 다음은 예입니다.

Promise Chaining :

function logFetch(url) {
  return fetch(url)
    .then(response => response.text())
    .then(text => {
      console.log(text);
    }).catch(err => {
      console.error('fetch failed', err);
    });
}

Async 함수:

async function logFetch(url) {
  try {
    const response = await fetch(url);
    console.log(await response.text());
  }
  catch (err) {
    console.log('fetch failed', err);
  }
}

위의 예에서는 await프라 미스 ( fetch(url))가 해결되거나 거부 될 때까지 기다립니다 . promise가 해결되면 값이 response변수에 저장되고 promise가 거부되면 오류가 발생하여 catch블록에 들어갑니다 .

우리는 이미 async/ 사용 await이 promise chaining보다 더 읽기 쉽다는 것을 알 수 있습니다. 이것은 우리가 사용하는 약속의 양이 증가 할 때 특히 그렇습니다. Promise chaining 및 async/ await콜백 지옥 문제를 해결하고 선택하는 방법은 개인 취향에 따라 다릅니다.


7

장단점과의 완전한 비교.

일반 JavaScript

  • 장점
  • 추가 라이브러리 또는 기술이 필요하지 않습니다.
  • 최고의 성능 제공
  • 타사 라이브러리와의 최고 수준의 호환성 제공
  • 임시 및 고급 알고리즘 생성 가능
  • 단점
  • 추가 코드와 비교적 복잡한 알고리즘이 필요할 수 있음

비동기 (라이브러리)

  • 장점
  • 가장 일반적인 제어 흐름 패턴 단순화
  • 여전히 콜백 기반 솔루션 임
  • 좋은 성능
  • 단점
  • 외부 종속성을 도입합니다.
  • 고급 흐름에는 여전히 충분하지 않을 수 있습니다.

약속

  • 장점
  • 가장 일반적인 제어 흐름 패턴을 대폭 단순화
  • 강력한 오류 처리
  • ES2015 사양의 일부
  • onFulfilled 및 onRejected의 지연된 호출을 보장합니다.
  • 단점
  • Promisify 콜백 기반 API 필요
  • 작은 성능 히트를 소개합니다

발전기

  • 장점
  • 비 차단 API를 차단하는 것처럼 보이게합니다.
  • 오류 처리 단순화
  • ES2015 사양의 일부
  • 단점
  • 보완적인 제어 흐름 라이브러리 필요
  • 비 순차적 흐름을 구현하기 위해 여전히 콜백 또는 약속이 필요합니다.
  • 생성기 기반이 아닌 API를 thunkify 또는 promisify해야합니다.

비동기 대기

  • 장점
  • 비 차단 API를 차단처럼 보이게합니다.
  • 깔끔하고 직관적 인 구문
  • 단점
  • 오늘날 사용하려면 Babel 또는 기타 트랜스 파일러와 일부 구성이 필요합니다.

이게 어디에서 복사 되었나요? 적어도 일부는 Node.js Design Patterns (제 2 판) (ISBN-10 : 1785885588)
Peter Mortensen

6

Async / await는 복잡한 제어 흐름이 필요한 경우 코드를 더 깔끔하고 읽기 쉽게 만드는 데 도움이됩니다. 또한 디버그 친화적 인 코드를 생성합니다. 그리고 단지 .NET으로 동기 및 비동기 오류를 모두 처리 할 수 ​​있습니다 try/catch.

최근에 코드 예제를 사용하여 몇 가지 일반적인 사용 사례에서 async / await의 장점을 보여주는이 게시물을 작성했습니다. JavaScript Async / Await가 약속을 어기는 6 가지 이유 (튜토리얼)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.