제너레이터는 JavaScript의 가장 강력한 기능 중 하나이며 필요에 따라 일시 중지하고 다시 시작할 수 있는 코드를 작성할 수 있게 해줍니다. 모든 코드를 한 번에 실행하는 일반 함수와 달리 생성기는 지연 실행을 사용하여 값을 증분적으로 반환하므로 데이터 시퀀스, 반복 또는 장기 실행 프로세스 작업이 더 쉬워집니다.
JavaScript에서 생성기는 function* 키워드를 사용하여 정의되고, Yield 키워드와 결합되어 함수를 부분적으로 실행할 수 있습니다. 생성기 함수를 호출할 때마다 즉시 실행되지는 않지만 제어된 실행을 허용하는 반복자를 반환합니다.
예:
const id = (function* () { let i = 1; while (true) { yield i; i = 1; } })();
이 예에서 함수 발생기는 무한한 숫자 시퀀스를 반환하며, 각 숫자는 필요할 때만 생성되고 반환됩니다.
yield 키워드는 생성기의 실행을 중지하고 값을 외부 세계에 반환합니다. 다음 함수 호출(next() 사용)에서 생성기는 중단된 부분부터 계속됩니다.
생성기를 호출하는 방법은 다음과 같습니다.
console.log(id.next().value); // 1 console.log(id.next().value); // 2 console.log(id.next().value); // 3
next()를 호출할 때마다 배열의 다음 값이 반환되고 다음 생성 시 함수가 일시 중지됩니다.
게으름:
생성기는 모든 것을 한 번에 실행하지 않고 필요할 때만 값을 생성합니다. 이는 무한 시퀀스 또는 대규모 데이터 배열 작업에 이상적입니다.
흐름 제어:
기능을 일시 중지하고 다시 시작할 수 있으므로 장기 실행 프로세스를 더 효과적으로 제어할 수 있습니다.
효율성:
모든 값을 메모리에 저장하는 대신 생성기가 한 번에 하나씩 반환하므로 메모리 소비가 줄어듭니다.
생성기는 유용하지만 몇 가지 잠재적인 문제가 있습니다.
복잡한 흐름 제어:
일시 중지하고 다시 시작하면 특히 복잡한 시나리오에서 코드를 이해하고 디버깅하기가 더 어려워질 수 있습니다.
성능:
경우에 따라 코드를 일시 중지하고 다시 시작하면 추가 오버헤드가 발생하여 효율성이 저하될 수 있습니다.
제한적:
호출당 하나의 값이 반환되므로 한 번에 많은 데이터에 액세스해야 하는 경우 비효율적일 수 있습니다.
호환성:
생성기는 ECMAScript 2015(ES6) 표준의 일부이므로 구형 브라우저에서는 Babel과 같은 추가 도구 없이는 이를 지원하지 않을 수 있습니다.
생성기가 너무 복잡해지면 대안을 고려해 볼 수 있습니다.
콜백을 사용한 재귀 함수:
function generateID(callback, start = 1) { callback(start); setTimeout(() => generateID(callback, start 1), 0); }
장점:
더 쉬운 흐름 제어: 재귀를 사용하지만 프로그램 흐름 제어 측면에서 함수가 더 읽기 쉽고 명확합니다.
비동기 실행: setTimeout을 사용하면 비동기 작업이 가능해 성능을 유지하는 데 도움이 됩니다.
단점:
재귀 오버헤드: 매우 많은 반복의 경우 재귀 문제(스택 오버플로)가 발생할 수 있습니다.
루프:
미리 결정된 개수의 값을 생성하는 간단한 루프는 더 작은 배열의 경우 더 효율적인 옵션이 될 수 있습니다.
function generateIDs(limit) { const ids = []; for (let i = 1; i
장점:
간단한 구현: 이 솔루션은 이해하기 쉽고 흐름 제어에 문제가 없습니다.
빠른 생성: 모든 값이 한 번에 생성되므로 반복 횟수가 적어 더 효율적일 수 있습니다.
단점:
메모리 소비: 모든 값은 메모리에 저장되므로 대규모 배열의 경우 문제가 될 수 있습니다.
게으름 없음: 모든 ID가 사전 생성되므로 모두 필요하지 않으면 비효율적일 수 있습니다.
반복자:
.next() 메서드를 통해 반복 가능한 값을 반환하는 객체로, 생성기와 유사하지만 더 많은 제어가 가능합니다.
function createIDIterator() { let i = 1; return { next() { return { value: i , done: false }; } }; } const idIterator = createIDIterator(); console.log(idIterator.next().value); // 1 console.log(idIterator.next().value); // 2 console.log(idIterator.next().value); // 3
장점:
흐름 제어: 생성기와 기능이 비슷하지만 실행이 더 선형적입니다.
더 간단한 코드: 산출량이 없으므로 코드를 더 쉽게 따라갈 수 있습니다.
단점:
자동 일시 중지 없음: 반복을 수동으로 관리해야 하는데, 이는 경우에 따라 불편할 수 있습니다.
async/await를 사용한 비동기 생성
ID가 비동기적으로 생성되는 경우 Promise를 반환하는 함수와 함께 async/await를 사용할 수 있습니다.
async function generateID(start = 1) { let i = start; while (true) { await new Promise((resolve) => setTimeout(resolve, 0)); console.log(i ); } } generateID();
장점:
비동기 실행: 주요 실행 흐름을 차단하지 않고 장기 실행 작업을 효율적으로 처리합니다.
최신 구문: async/await는 비동기 코드를 사용하는 보다 현대적이고 직관적인 방법입니다.
단점:
동기 코드에 적합하지 않음: 동기 생성이 필요한 경우 이 솔루션은 이상적이지 않습니다.
생성기는 크고 무한한 데이터 배열로 작업할 뿐만 아니라 프로세스를 일시 중지하고 다시 시작해야 하는 애플리케이션의 흐름 제어를 위한 훌륭한 도구입니다. 그러나 복잡성과 잠재적인 성능 문제로 인해 주의해서 사용해야 합니다. 애플리케이션의 요구 사항에 따라 반복, 재귀 또는 비동기 코드와 같은 대체 솔루션이 더 적합할 수 있습니다.
부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3