저는 Java 개발자로 일했는데 처음으로 JavaScript의 Promise를 접했던 기억이 납니다. 개념은 단순해 보이지만 Promise가 어떻게 작동하는지 완전히 이해할 수는 없었습니다. 프로젝트에서 이를 사용하기 시작하고 그들이 해결한 사례를 이해했을 때 상황이 바뀌었습니다. 그러다가 AHA 순간이 왔고 모든 것이 더욱 명확해졌습니다. 시간이 지나면서 Promises는 내 도구 벨트의 귀중한 무기가 되었습니다. 직장에서 사용할 수 있고, 함수 간 비동기 처리 문제를 해결할 수 있어서 묘하게 만족스럽습니다.
아마도 API에서 데이터를 가져올 때 Promise를 처음 접하게 될 것입니다. 이는 가장 일반적인 예이기도 합니다. 최근 인터뷰를 했는데 첫 번째 질문인 “Promise와 Async Await의 차이점을 알려주실 수 있나요?”가 무엇이었을까요? 나는 그것이 지원자가 메커니즘의 작동 방식을 어떻게 이해하는지 더 잘 알 수 있는 좋은 출발점이라고 생각하기 때문에 이를 환영합니다. 그러나 그 또는 그녀는 대부분 다른 라이브러리와 프레임워크를 사용하고 있습니다. 이를 통해 차이점을 기록하고 비동기 함수 오류 처리에 대한 모범 사례를 설명할 수 있었습니다.
첫 번째 질문인 "약속은 무엇입니까?"부터 시작하겠습니다. Promise는 우리가 아직 모르는 값에 대한 자리 표시자이지만 비동기 계산/함수의 결과로 해당 값을 얻게 됩니다. 약속이 잘되면 결과가 나오겠죠. Promise가 제대로 진행되지 않으면 Promise는 오류를 반환합니다.
생성자를 호출하고 두 개의 콜백 함수인 resolve 및 거부.
를 전달하여 Promise를 정의합니다.
const newPromise = new Promise((resolve, reject) => { resolve('Hello'); // reject('Error'); });
Promise를 성공적으로 해결하려면 해결 함수를 호출합니다. Reject는 로직을 평가하는 동안 오류가 발생할 경우 Promise를 거부하는 것입니다.
Promise의 결과를 얻기 위해 내장된 함수를 사용합니다. 두 개의 전달된 콜백(결과 및 오류)이 있습니다. Resolve 함수에 의해 Promise가 성공적으로 해결되면 결과가 호출됩니다. Promise가 해결되지 않으면 두 번째 함수 오류가 호출됩니다. 이 함수는 거부 또는 발생한 다른 오류에 의해 트리거됩니다.
newPromise.then(result => { console.log(result); // Hello }, error => { console.log("There shouldn't be an error"); });
이 예에서는 Promise를 성공적으로 해결했기 때문에 Hello라는 결과를 얻게 됩니다.
Promise가 거부되면 항상 두 번째 오류 콜백이 호출됩니다.
const newPromise1 = new Promise((resolve, reject) => { reject('An error occurred in Promise1'); }); newPromise1.then( (result) => { console.log(result); // It is not invoked }, (error) => { console.log(error); // 'An error occurred in Promise1' } );
명확성을 위해 더 권장되는 접근 방식은 내장된 catch 메서드를 사용하는 것입니다.
const newPromise2 = new Promise((resolve, reject) => { reject('An error occurred in Promise2'); }); newPromise2 .then((result) => { console.log(result); // It is not invoked }) .catch((error) => { console.log(error); // 'An error occurred in Promise2' });
catch 메소드는 연결되어 있으며 자체 오류 콜백을 제공했습니다. Promise가 거부되면 호출됩니다.
두 버전 모두 잘 작동하지만 체인 연결이 IMO에서 더 읽기 쉽고 더 자세히 다루는 다른 내장 방법을 사용할 때 편리합니다.
Promise의 결과는 또 다른 Promise가 될 수도 있습니다. 이 경우 임의 개수의 then 함수를 연결할 수 있습니다.
getJSON('categories.json') .then(categories => { console.log('Fetched categories:', categories); return getJSON(categories[0].itemsUrl); }) .then(items => { console.log('Fetched items:', items); return getJSON(items[0].detailsUrl); }) .then(details => { console.log('Fetched details:', details); }) .catch(error => { console.error('An error has occurred:', error.message); });
이 예에서는 검색 결과를 좁혀 세부 데이터를 얻는 역할을 합니다. 각 then 함수에는 오류 콜백이 있을 수도 있습니다. 호출 체인에서 오류를 잡는 것에만 관심이 있다면 catch 기능을 활용할 수 있습니다. Promise 중 하나라도 오류를 반환하면 평가됩니다.
때때로 우리는 좀 더 독립적인 약속의 결과를 기다리고 그 결과에 따라 행동하고 싶을 때가 있습니다. Promise가 어떻게 해결되었는지 순서에 관심이 없다면 내장 함수 Promise.all을 사용할 수 있습니다.
Promise.all([ getJSON('categories.json'), getJSON('technology_items.json'), getJSON('science_items.json') ]) .then(results => { const categories = results[0]; const techItems = results[1]; const scienceItems = results[2]; console.log('Fetched categories:', categories); console.log('Fetched technology items:', techItems); console.log('Fetched science items:', scienceItems); // Fetch details of the first item in each category return Promise.all([ getJSON(techItems[0].detailsUrl), getJSON(scienceItems[0].detailsUrl) ]); }) .then(detailsResults => { const laptopDetails = detailsResults[0]; const physicsDetails = detailsResults[1]; console.log('Fetched laptop details:', laptopDetails); console.log('Fetched physics details:', physicsDetails); }) .catch(error => { console.error('An error has occurred:', error.message); });
Promise.all은 약속 배열을 가져와서 결과 배열을 반환합니다. Promise 중 하나가 거부되면 Promise.all도 거부됩니다.
또 다른 내장 기능은 Promise.race입니다. 여러 비동기 함수(Promise)가 있고 이를 경주하고 싶을 때 사용됩니다.
Promise.race([ getJSON('technology_items.json'), getJSON('science_items.json') ]) .then(result => { console.log('First resolved data:', result); }) .catch(error => { console.error('An error has occurred:', error.message); });
Promise 실행에는 다양한 시간이 걸릴 수 있으며 Promise.race는 배열에서 첫 번째로 해결되거나 거부된 Promise를 평가합니다. 순서는 상관없지만 가장 빠른 비동기 호출의 결과를 원할 때 사용됩니다.
보시다시피 Promise를 작성하려면 많은 상용구 코드가 필요합니다. 운 좋게도 Promise를 더욱 쉽게 사용할 수 있는 기본 Async Await 기능이 있습니다. async라는 단어로 함수를 표시하면 코드 어딘가에서 비동기 함수를 호출할 것이므로 기다리지 말아야 함을 의미합니다. 그런 다음 비동기 함수가 대기 단어와 함께 호출됩니다.
const fetchData = async () => { try { // Fetch the categories const categories = await getJSON('categories.json'); console.log('Fetched categories:', categories); // Fetch items from the first category (Technology) const techItems = await getJSON(categories[0].itemsUrl); console.log('Fetched technology items:', techItems); // Fetch details of the first item in Technology (Laptops) const laptopDetails = await getJSON(techItems[0].detailsUrl); console.log('Fetched laptop details:', laptopDetails); } catch (error) { console.error('An error has occurred:', error.message); } }; fetchData();
fetchData는 async로 표시되어 있으며 이를 통해 함수 내에서 비동기 호출을 처리하기 위해 wait를 사용할 수 있습니다. 우리는 더 많은 Promise를 호출하고 차례로 평가할 것입니다.
오류를 처리하려면 try...catch 블록을 사용합니다. 거부된 오류는 catch 블록에 포착되며 오류를 기록하는 것과 같은 조치를 취할 수 있습니다.
두 가지 모두 비동기 코드를 사용한 JavaScript 처리 기능입니다. 주요 차이점은 Promise가 then 및 catch와 함께 체인을 사용하는 경우 구문에 있지만 비동기 대기 구문은 동기식 방식에 더 가깝습니다. 읽기가 더 쉬워집니다. 비동기 대기에 대한 오류 처리는 try...catch 블록을 활용하면 더 간단해집니다. 면접에서 쉽게 접할 수 있는 질문입니다. 답변하는 동안 두 가지에 대한 설명을 더 자세히 알아보고 차이점을 강조할 수 있습니다.
Promise 기능
물론 비동기 대기를 통해 모든 기능을 사용할 수 있습니다. 예를 들어 Promise.all.
const fetchAllData = async () => { try { // Use await with Promise.all to fetch multiple JSON files in parallel const [techItems, scienceItems, laptopDetails] = await Promise.all([ getJSON('technology_items.json'), getJSON('science_items.json'), getJSON('laptops_details.json') ]); console.log('Fetched technology items:', techItems); console.log('Fetched science items:', scienceItems); console.log('Fetched laptop details:', laptopDetails); } catch (error) { console.error('An error occurred:', error.message); } };
프라미스는 비동기 코드를 처리하기 위한 JavaScript의 기본 기능입니다. 사용되는 주요 방법은 다음과 같습니다.
위의 예에서 이미 표시된 것처럼 이는 Promise에 대해 가장 많이 사용되는 사용 사례 중 하나이며 매일 작업합니다.
Promise를 사용하여 비동기식으로 파일을 읽고 쓸 수 있습니다. 특히 Node.js 모듈 fs.promises를 사용하면 더욱 그렇습니다.
import * as fs from 'fs/promises'; const writeFileAsync = async (filePath, content, options = {}) => { try { await fs.writeFile(filePath, content, options); console.log(`File successfully written to ${filePath}`); } catch (error) { console.error(`Error writing file to ${filePath}:`, error.message); } }; const filePath = 'output.txt'; const fileContent = 'Hello, this is some content to write to the file!'; const fileOptions = { encoding: 'utf8', flag: 'w' }; // Optional file write options writeFileAsync(filePath, fileContent, fileOptions);
Axios는 여러분이 꼭 알아야 할 라이브러리입니다. Axios는 클라이언트에서 HTTP 요청을 처리하며 널리 사용됩니다.
Express는 Node.js용 웹 프레임워크입니다. 이를 통해 웹 앱과 API를 쉽게 구축할 수 있으며 Express에서 Promise를 사용하면 코드가 깔끔하게 유지되고 관리하기 쉽습니다.
모든 예제는 https://github.com/PrincAm/promise-example에서 찾을 수 있습니다.
프라미스는 JavaScript의 기본 부분으로, 웹 개발에서 비동기 작업을 처리하는 데 필수적입니다. 데이터를 가져오거나, 파일로 작업하거나, Axios 및 Express와 같은 널리 사용되는 라이브러리를 사용할 때 코드에서 Promise를 자주 사용하게 됩니다.
이 글에서는 Promise가 무엇인지, 그 결과를 정의하고 검색하는 방법, 오류를 효과적으로 처리하는 방법을 살펴보았습니다. 또한 체인, Promise.all 및 Promise.race와 같은 주요 기능도 다루었습니다. 마지막으로 Promise를 사용하는 보다 간단한 방법을 제공하는 async Wait 구문을 도입했습니다.
이러한 개념을 이해하는 것은 JavaScript 개발자에게 매우 중요합니다. 왜냐하면 이러한 개념은 매일 사용하는 도구이기 때문입니다.
아직 시도하지 않았다면 API에서 데이터를 가져오는 간단한 코드 조각을 작성하는 것이 좋습니다. 실험할 수 있는 재미있는 API로 시작할 수 있습니다. 또한 이 저장소에서 모든 예제와 코드 조각을 탐색할 수 있습니다.
부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3