{"componentChunkName":"component---src-templates-blog-post-js","path":"/yagmyagm/asynawait/","result":{"data":{"site":{"siteMetadata":{"title":"Zayden","author":"[Your Name]","siteUrl":"https://gatsby-starter-bee.netlify.com","comment":{"disqusShortName":"","utterances":"JaeYeopHan/gatsby-starter-bee"},"sponsor":{"buyMeACoffeeId":"jbee"}}},"markdownRemark":{"id":"1ad59e1d-f0e8-5acf-969d-e20a5e071d16","excerpt":"이번 글에서는 우리가 자주 사용하는 async, await 관련해서 살펴보겠습니다. async, await에 대한 사용하는 방법에 대한 부분은 다루지 않고 어떻게 구현되어있는지에 대하여 알아보겠습니다. async-await async-await은 ECMAScript 2017에서 표준으로 정의되었습니다. 비동기 프로그래밍을 동기 방식처럼 직관적으로 표현할 수 있고, callback…","html":"<p>이번 글에서는 우리가 자주 사용하는 async, await 관련해서 살펴보겠습니다. async, await에 대한 사용하는 방법에 대한 부분은 다루지 않고 어떻게 구현되어있는지에 대하여 알아보겠습니다.</p>\n<br/>\n<h3 id=\"async-await\" style=\"position:relative;\"><a href=\"#async-await\" aria-label=\"async await permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>async-await</h3>\n<p>async-await은 <strong>ECMAScript 2017</strong>에서 표준으로 정의되었습니다. 비동기 프로그래밍을 동기 방식처럼 직관적으로 표현할 수 있고, callback 지옥 문제를 해결해 줍니다.</p>\n<p>비동기 로직을 쉽게 작성하기 위해, 즉 비동기가 들어간 비즈니스 로직은 중첩될수록 그 복잡도가 기하 급수적으로 늘어나며, 이를 간결하게 하여 유지보수성 향상에 기여할 수 있습니다.</p>\n<p>그러나 한가지 문제점은 <strong>ECMAScript 2017</strong>를 지원하지 않는 하위 버전에 브라우저에서는 사용할 수 없다는 단점이 있습니다. 그래서 Babel과 같은 트랜스파일러를 이용하여 하위 버전 브라우저에서 이해 할 수 있는 <strong>ECMAScript 2016</strong>문법으로 변환을 하면 사용할 수 있습니다.</p>\n<p>그러면 여기서 한가지 알 수 있는것은 <strong>ECMAScript 2016</strong>로 변환한다는 의미는 <strong>ECMAScript 2016</strong>로 구현이 가능하다는 것입니다. async-await 구문이 어떻게 <strong>ECMAScript 2016</strong> 문법으로 표현되는지 알아 보겠습니다.</p>\n<br/>\n<h3 id=\"async-await을-바벨로-변환\" style=\"position:relative;\"><a href=\"#async-await%EC%9D%84-%EB%B0%94%EB%B2%A8%EB%A1%9C-%EB%B3%80%ED%99%98\" aria-label=\"async await을 바벨로 변환 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>async-await을 바벨로 변환</h3>\n<p>async-await 구문을 바벨을 이용하여 변환하게 된다면 아래와 같이 <code class=\"language-text\">promise</code> 와 <code class=\"language-text\">generator</code>로 구현되어 있는것을 확인 할 수 있습니다.</p>\n<p>변환할 수 있는 사이트는 <a href=\"https://babeljs.io/repl#?browsers=chrome%2050&#x26;build=&#x26;builtIns=false&#x26;corejs=3.21&#x26;spec=false&#x26;loose=false&#x26;code_lz=IYZwngdgxgBAZgV2gFwJYHsIxMAtgBwBsBTACgEoYBvAKAEhgB3YVZGYfVCgbhoF8gA&#x26;debug=false&#x26;forceAllTransforms=false&#x26;modules=false&#x26;shippedProposals=false&#x26;circleciRepo=&#x26;evaluate=false&#x26;fileSize=false&#x26;timeTravel=false&#x26;sourceType=module&#x26;lineWrap=true&#x26;presets=env&#x26;prettier=true&#x26;targets=&#x26;version=7.22.10&#x26;externalPlugins=&#x26;assumptions=%7B%7D\" title=\"바벨로 변환\">바벨로 변환</a>을 참조 해주시면 됩니다.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token operator\">**</span>ECMAScript <span class=\"token number\">2017</span><span class=\"token operator\">**</span>\n<span class=\"token keyword\">async</span> <span class=\"token keyword\">function</span> <span class=\"token function\">sample</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token keyword\">await</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"api\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token operator\">**</span>ECMAScript <span class=\"token number\">2016</span><span class=\"token operator\">**</span>\n<span class=\"token keyword\">function</span> <span class=\"token function\">asyncGeneratorStep</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">gen<span class=\"token punctuation\">,</span> resolve<span class=\"token punctuation\">,</span> reject<span class=\"token punctuation\">,</span> _next<span class=\"token punctuation\">,</span> _throw<span class=\"token punctuation\">,</span> key<span class=\"token punctuation\">,</span> arg</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">try</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">var</span> info <span class=\"token operator\">=</span> gen<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span><span class=\"token punctuation\">(</span>arg<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">var</span> value <span class=\"token operator\">=</span> info<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span> <span class=\"token keyword\">catch</span> <span class=\"token punctuation\">(</span>error<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">reject</span><span class=\"token punctuation\">(</span>error<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>info<span class=\"token punctuation\">.</span>done<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">resolve</span><span class=\"token punctuation\">(</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n    Promise<span class=\"token punctuation\">.</span><span class=\"token function\">resolve</span><span class=\"token punctuation\">(</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span>_next<span class=\"token punctuation\">,</span> _throw<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">_asyncToGenerator</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">fn</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> <span class=\"token keyword\">function</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">var</span> self <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">,</span>\n      args <span class=\"token operator\">=</span> arguments<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Promise</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">resolve<span class=\"token punctuation\">,</span> reject</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">var</span> gen <span class=\"token operator\">=</span> <span class=\"token function\">fn</span><span class=\"token punctuation\">.</span><span class=\"token function\">apply</span><span class=\"token punctuation\">(</span>self<span class=\"token punctuation\">,</span> args<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">function</span> <span class=\"token function\">_next</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">value</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">asyncGeneratorStep</span><span class=\"token punctuation\">(</span>gen<span class=\"token punctuation\">,</span> resolve<span class=\"token punctuation\">,</span> reject<span class=\"token punctuation\">,</span> _next<span class=\"token punctuation\">,</span> _throw<span class=\"token punctuation\">,</span> <span class=\"token string\">\"next\"</span><span class=\"token punctuation\">,</span> value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span>\n      <span class=\"token keyword\">function</span> <span class=\"token function\">_throw</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">err</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">asyncGeneratorStep</span><span class=\"token punctuation\">(</span>gen<span class=\"token punctuation\">,</span> resolve<span class=\"token punctuation\">,</span> reject<span class=\"token punctuation\">,</span> _next<span class=\"token punctuation\">,</span> _throw<span class=\"token punctuation\">,</span> <span class=\"token string\">\"throw\"</span><span class=\"token punctuation\">,</span> err<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span>\n      <span class=\"token function\">_next</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">undefined</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">sample</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> <span class=\"token function\">_sample</span><span class=\"token punctuation\">.</span><span class=\"token function\">apply</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">,</span> arguments<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">_sample</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  _sample <span class=\"token operator\">=</span> <span class=\"token function\">_asyncToGenerator</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span><span class=\"token operator\">*</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">yield</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"api\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">return</span> <span class=\"token function\">_sample</span><span class=\"token punctuation\">.</span><span class=\"token function\">apply</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">,</span> arguments<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<br/>\n<h3 id=\"async-await-과-promise-generator\" style=\"position:relative;\"><a href=\"#async-await-%EA%B3%BC-promise-generator\" aria-label=\"async await 과 promise generator permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>async-await 과 promise, generator</h3>\n<p>바벨로 변환된 코드에 대하여 살펴보겠습니다.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token operator\">**</span>변환 전<span class=\"token operator\">**</span>\n<span class=\"token keyword\">async</span> <span class=\"token keyword\">function</span> <span class=\"token function\">sample</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token keyword\">await</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"api\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token operator\">**</span>변환 후<span class=\"token operator\">**</span>\n<span class=\"token keyword\">function</span> <span class=\"token function\">_sample</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  _sample <span class=\"token operator\">=</span> <span class=\"token function\">_asyncToGenerator</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span><span class=\"token operator\">*</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">yield</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"api\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>변환된 코드를 간략히 하였습니다. 위 코드를 봤을때 무언가 차이점이 보이시나요? 제가 봤을때는 <code class=\"language-text\">await</code> 이 <code class=\"language-text\">yield</code> 로 바뀌고 <code class=\"language-text\">async</code> 가 <code class=\"language-text\">function* () {}</code> (제너레이터)로 바뀐것 같이 보이는데요. 일단 지금은 <code class=\"language-text\">_asyncToGenerator</code> 함수에 대해서는 잠시 보류하면 결국 async-await 은 제너레이터를 사용하여 구현되었다고 볼 수 있겠네요.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">function</span><span class=\"token operator\">*</span> <span class=\"token function\">gen</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">yield</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">const</span> generator <span class=\"token operator\">=</span> <span class=\"token function\">gen</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">const</span> one <span class=\"token operator\">=</span> gen<span class=\"token punctuation\">.</span><span class=\"token function\">next</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nconsole<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span>one<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// 1 출력</span></code></pre></div>\n<p>여기서 제너레이터에 대하여 간단히 설명하자면 제너레이터 함수를 실행하고 반환되어진 객체에 next() 메소드를 실행을 하였을때 가장 가까운 yield 문을 만날때까지 실행이 되고 해당 값이 반환 됩니다.</p>\n<p>따라서 비동기 로직이 종료되었을 때마다 적절하게 next() 메서드를 호출해주기만 하면, async-await이 구현되어 지는것입니다.</p>\n<p>그러면 이번에는 <code class=\"language-text\">_asyncToGenerator</code> 살펴보겠습니다.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">function</span> <span class=\"token function\">_asyncToGenerator</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">fn</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> <span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">var</span> self <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">,</span>\n      args <span class=\"token operator\">=</span> arguments<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Promise</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">resolve<span class=\"token punctuation\">,</span> reject</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">var</span> gen <span class=\"token operator\">=</span> <span class=\"token function\">fn</span><span class=\"token punctuation\">.</span><span class=\"token function\">apply</span><span class=\"token punctuation\">(</span>self<span class=\"token punctuation\">,</span> args<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">function</span> <span class=\"token function\">_next</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">value</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">asyncGeneratorStep</span><span class=\"token punctuation\">(</span>gen<span class=\"token punctuation\">,</span> resolve<span class=\"token punctuation\">,</span> reject<span class=\"token punctuation\">,</span> _next<span class=\"token punctuation\">,</span> _throw<span class=\"token punctuation\">,</span> <span class=\"token string\">'next'</span><span class=\"token punctuation\">,</span> value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span>\n      <span class=\"token keyword\">function</span> <span class=\"token function\">_throw</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">err</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">asyncGeneratorStep</span><span class=\"token punctuation\">(</span>gen<span class=\"token punctuation\">,</span> resolve<span class=\"token punctuation\">,</span> reject<span class=\"token punctuation\">,</span> _next<span class=\"token punctuation\">,</span> _throw<span class=\"token punctuation\">,</span> <span class=\"token string\">'throw'</span><span class=\"token punctuation\">,</span> err<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span>\n      <span class=\"token function\">_next</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">undefined</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><code class=\"language-text\">_asyncToGenerator</code> 함수는 함수를 인자로 받고 함수를 반환하고 있는것 같습니다. 반환하는 함수에 대하여 자세히 살펴보겠습니다.</p>\n<p>여기서 인자로 전달 받은 함수는 다음과 같습니다.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">function</span><span class=\"token operator\">*</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">yield</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"api\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>반환하는 함수는 다음과 같습니다.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">function</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Promise</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">resolve<span class=\"token punctuation\">,</span> reject</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\n    ## 제너레이터 함수를 실행하여 반환되어진 제너레이터 객체\n    <span class=\"token keyword\">var</span> gen <span class=\"token operator\">=</span> <span class=\"token function\">fn</span><span class=\"token punctuation\">.</span><span class=\"token function\">apply</span><span class=\"token punctuation\">(</span>self<span class=\"token punctuation\">,</span> args<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">function</span> <span class=\"token function\">_next</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">value</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">asyncGeneratorStep</span><span class=\"token punctuation\">(</span>gen<span class=\"token punctuation\">,</span> resolve<span class=\"token punctuation\">,</span> reject<span class=\"token punctuation\">,</span> _next<span class=\"token punctuation\">,</span> _throw<span class=\"token punctuation\">,</span> <span class=\"token string\">\"next\"</span><span class=\"token punctuation\">,</span> value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">function</span> <span class=\"token function\">_throw</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">err</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">asyncGeneratorStep</span><span class=\"token punctuation\">(</span>gen<span class=\"token punctuation\">,</span> resolve<span class=\"token punctuation\">,</span> reject<span class=\"token punctuation\">,</span> _next<span class=\"token punctuation\">,</span> _throw<span class=\"token punctuation\">,</span> <span class=\"token string\">\"throw\"</span><span class=\"token punctuation\">,</span> err<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token function\">_next</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">undefined</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>위 코드와 같이 반한되어진 함수는 <code class=\"language-text\">promise</code>를 반환하고 있네요. <code class=\"language-text\">promise</code>의 콜백 함수를 보면 <code class=\"language-text\">_next</code> , <code class=\"language-text\">_throw</code> 메서드가 선언되어 있는것으로 보입니다. 두 함수 내부에는 <code class=\"language-text\">asyncGeneratorStep</code> 함수를 호출하고 있습니다.</p>\n<p><code class=\"language-text\">asyncGeneratorStep</code> 함수는 제너레이터 객체, resolve, reject 등등 다양한 인자를 전달하여 호출하고 있습니다.</p>\n<p>여기까지 봤을때는 아직도 세부 구현이 어떻게 돌아가고 있는지 잘 파악이 되지 않습니다. 그래서 조금 더 깊이 들어보겠습니다.</p>\n<p>이번에는 <code class=\"language-text\">asyncGeneratorStep</code> 함수에 대하여 살펴보겠습니다.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">## gen<span class=\"token operator\">:</span> 제너레이터 함수를 실행하여 반환되어진 제너레이터 객체\n<span class=\"token keyword\">function</span> <span class=\"token function\">asyncGeneratorStep</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">gen<span class=\"token punctuation\">,</span> resolve<span class=\"token punctuation\">,</span> reject<span class=\"token punctuation\">,</span> _next<span class=\"token punctuation\">,</span> _throw<span class=\"token punctuation\">,</span> key<span class=\"token punctuation\">,</span> arg</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">try</span> <span class=\"token punctuation\">{</span>\n\n    ## gen<span class=\"token punctuation\">.</span><span class=\"token function\">next</span><span class=\"token punctuation\">(</span>arg<span class=\"token punctuation\">)</span> or gen<span class=\"token punctuation\">.</span><span class=\"token function\">throw</span><span class=\"token punctuation\">(</span>arg<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">var</span> info <span class=\"token operator\">=</span> gen<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span><span class=\"token punctuation\">(</span>arg<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    ## <span class=\"token punctuation\">{</span> value<span class=\"token operator\">:</span> <span class=\"token keyword\">yield</span> 구문에 있는 어떠한 로직이 실행되고 나서 결과값<span class=\"token punctuation\">,</span> done<span class=\"token operator\">:</span> 모든 <span class=\"token keyword\">yield</span> 구문이 실행 여부 <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">var</span> value <span class=\"token operator\">=</span> info<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span> <span class=\"token keyword\">catch</span> <span class=\"token punctuation\">(</span>error<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">reject</span><span class=\"token punctuation\">(</span>error<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>info<span class=\"token punctuation\">.</span>done<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    ## 제너레이터의 모든 <span class=\"token keyword\">yield</span> 구문이 처리가 되었을때\n    <span class=\"token function\">resolve</span><span class=\"token punctuation\">(</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n    Promise<span class=\"token punctuation\">.</span><span class=\"token function\">resolve</span><span class=\"token punctuation\">(</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span>_next<span class=\"token punctuation\">,</span> _throw<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>전달 받은 gen(제너레이터 객체)에 key는 “next” or “throw”이므로 <code class=\"language-text\">gen[key]()</code>는 <code class=\"language-text\">gen[next]() (gen.next())</code> <code class=\"language-text\">gen[throw] (gen.throw())</code>가 됩니다. 즉, 제너레이터의 next 함수, throw 함수를 실행하는 부분입니다. 그리고 실행할때는 인자로 넘어온 <code class=\"language-text\">arg</code> 값이 <code class=\"language-text\">next</code> 또는 <code class=\"language-text\">throw</code>가 호출될때 인자로 넘겨집니다.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">Promise<span class=\"token punctuation\">.</span><span class=\"token function\">resolve</span><span class=\"token punctuation\">(</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span>_next<span class=\"token punctuation\">,</span> _throw<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p><code class=\"language-text\">Promise.resolve(value)</code>는 결괏값이 <code class=\"language-text\">value</code>인 이행 상태 프라미스를 생성합니다. 그래서 프로미스가 이행된 값이 <code class=\"language-text\">then</code> 메소드의 첫번째 메소드인 <code class=\"language-text\">_next(프로미스 결과 값)</code>으로 호출됩니다. 그리고 프로미스가 “rejected” 상태이면 즉, 오류가 발생하면 두번째 메소드인 <code class=\"language-text\">_throw(에러)</code>가 실행됩니다.</p>\n<p>그러면 만약에서 여기서 <code class=\"language-text\">_next(프로미스 결과 값)</code>가 호출되면 다시 <code class=\"language-text\">asyncGeneratorStep</code>함수가 실행되고 이번엔 해당 함수가 실행되면서 <code class=\"language-text\">arg</code>로 인자로 프로미스가 이행된 결과 값을 전달하고 다시 <code class=\"language-text\">gen.next(프로미스 결과 값)</code> 이 실행됩니다. 그리고 제너레이터 <code class=\"language-text\">next</code> 함수에 인자로 넘어간 값은 <code class=\"language-text\">yield</code> 구문의 반환값으로 할당 됩니다.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">function</span><span class=\"token operator\">*</span> <span class=\"token function\">generator</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  ## next 함수 호출시 인자로 넘어간 값이 result에 할당 됩니다<span class=\"token punctuation\">.</span>\n  <span class=\"token keyword\">const</span> result <span class=\"token operator\">=</span> <span class=\"token keyword\">yield</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"api\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token operator\">&lt;</span>샘플 예시<span class=\"token operator\">></span>\n<span class=\"token keyword\">const</span> gen <span class=\"token operator\">=</span> <span class=\"token function\">generator</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\ngen<span class=\"token punctuation\">.</span><span class=\"token function\">next</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\ngen<span class=\"token punctuation\">.</span><span class=\"token function\">next</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"결과\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nresult 변수에는 <span class=\"token string\">\"결과\"</span>가 할당됩니다<span class=\"token punctuation\">.</span></code></pre></div>\n<p><strong>즉, 여기서 한번 정리를 하자면 asyncGeneratorStep 함수는 재귀함수를 통해 next() 메서드를 대신 호출하여 yield 구문의 결과 값이 나올때 next(“결과”) 호출할때 인자로 결과값을 넣어 yield 구문의 반환값을 할당하여 async-await 을 구현할 수 있습니다.</strong></p>\n<p>그리고 마지막으로는 해당 제너레이터 객체의 속성중 <code class=\"language-text\">done</code> 속성이 true 이면 해당 재귀함수는 멈춥니다. 즉, 제너레이터 함수의 모든 yield 구문을 처리하면 재귀함수는 멈춥니다.</p>\n<br/>\n<h3 id=\"async-await을-간단하게-구현해보기\" style=\"position:relative;\"><a href=\"#async-await%EC%9D%84-%EA%B0%84%EB%8B%A8%ED%95%98%EA%B2%8C-%EA%B5%AC%ED%98%84%ED%95%B4%EB%B3%B4%EA%B8%B0\" aria-label=\"async await을 간단하게 구현해보기 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>async-await을 간단하게 구현해보기</h3>\n<p>앞서서 설명드린 바벨로 변환되어진 코드는 조금 복잡하니 해당 부분을 간단하게 한번 구현해보도록 하겠습니다.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">function</span> <span class=\"token function\">api</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">time</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Promise</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">resolve</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">setTimeout</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">resolve</span><span class=\"token punctuation\">(</span>time<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> time<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">_asyncToGenerator</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">genFunc</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> <span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> gen <span class=\"token operator\">=</span> <span class=\"token function\">genFunc</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">function</span> <span class=\"token function\">next</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">value</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">const</span> genInfo <span class=\"token operator\">=</span> gen<span class=\"token punctuation\">.</span><span class=\"token function\">next</span><span class=\"token punctuation\">(</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n      <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>genInfo<span class=\"token punctuation\">.</span>done<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        Promise<span class=\"token punctuation\">.</span><span class=\"token function\">resolve</span><span class=\"token punctuation\">(</span>genInfo<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span>next<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token function\">next</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">function</span><span class=\"token operator\">*</span> <span class=\"token function\">sample</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> result <span class=\"token operator\">=</span> <span class=\"token keyword\">yield</span> <span class=\"token function\">api</span><span class=\"token punctuation\">(</span><span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span>result<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">const</span> asyncAwaitSample <span class=\"token operator\">=</span> <span class=\"token function\">_asyncToGenerator</span><span class=\"token punctuation\">(</span>sample<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token function\">asyncAwaitSample</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<br/>\n<hr>\n<p><a href=\"https://medium.com/@la.place/async-await%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EA%B5%AC%ED%98%84%ED%95%98%EB%8A%94%EA%B0%80-fa08a3157647\">https://medium.com/@la.place/async-await%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EA%B5%AC%ED%98%84%ED%95%98%EB%8A%94%EA%B0%80-fa08a3157647</a></p>","frontmatter":{"title":"알고 쓰자 - async, await","date":"August 12, 2023"}}},"pageContext":{"slug":"/yagmyagm/asynawait/","previous":{"fields":{"slug":"/frontendPerformance/font/"},"frontmatter":{"title":"폰트 최적화"}},"next":{"fields":{"slug":"/frontendPerformance/cache/"},"frontmatter":{"title":"캐시 최적화"}}}}}