> 웹 프론트엔드 > JS 튜토리얼 > JavaScript 생성기: 일시 중지 기능으로 코드를 강화하세요!

JavaScript 생성기: 일시 중지 기능으로 코드를 강화하세요!

Linda Hamilton
풀어 주다: 2024-12-30 22:29:11
원래의
999명이 탐색했습니다.

JavaScript Generators: Supercharge Your Code with Pausing Power!

JavaScript 생성기는 정말 멋지네요. 일반 기능과 비슷하지만 초능력이 있습니다. 저는 최근에 이 기능을 많이 사용해왔는데, 제 코드의 제어 흐름에 대한 제가 생각하는 방식이 바뀌었다고 말씀드리고 싶습니다.

기본부터 시작하겠습니다. 생성기는 일시 중지하고 다시 시작할 수 있는 기능입니다. function* 구문과 항복 키워드를 사용합니다. 다음은 간단한 예입니다.

function* countToThree() {
  yield 1;
  yield 2;
  yield 3;
}

const counter = countToThree();
console.log(counter.next().value); // 1
console.log(counter.next().value); // 2
console.log(counter.next().value); // 3
로그인 후 복사
로그인 후 복사

한 번에 하나씩 함수를 실행하는 방법을 알아보세요. 그게 발전기의 마법이죠.

하지만 생성기는 단순히 계산하는 것 이상의 일을 할 수 있습니다. 사용자 정의 반복자를 만드는 데 적합합니다. 피보나치 수열을 생성하고 싶다고 가정해 보겠습니다.

function* fibonacci() {
  let [prev, curr] = [0, 1];
  while (true) {
    yield curr;
    [prev, curr] = [curr, prev + curr];
  }
}

const fib = fibonacci();
for (let i = 0; i < 10; i++) {
  console.log(fib.next().value);
}
로그인 후 복사
로그인 후 복사

이 생성기는 계속해서 피보나치 수를 생성합니다. 무한 수열이지만 필요한 값만 계산합니다.

제너레이터의 가장 멋진 점 중 하나인 게으른 평가를 소개합니다. 그들은 우리가 요청할 때만 값을 계산합니다. 이는 대규모 데이터 세트나 복잡한 계산에 매우 효율적일 수 있습니다.

더 실제적인 예를 살펴보겠습니다. 대규모 데이터세트에 대한 페이지 매김 시스템을 구축한다고 가정해 보겠습니다.

function* paginate(items, pageSize) {
  for (let i = 0; i < items.length; i += pageSize) {
    yield items.slice(i, i + pageSize);
  }
}

const allItems = Array.from({ length: 100 }, (_, i) => i + 1);
const pageSize = 10;
const pages = paginate(allItems, pageSize);

console.log(pages.next().value); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(pages.next().value); // [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
로그인 후 복사
로그인 후 복사

이 생성기를 사용하면 모든 것을 메모리에 한 번에 로드할 필요 없이 필요할 때마다 데이터 페이지를 가져올 수 있습니다.

생성기는 비동기 프로그래밍에서도 빛을 발합니다. 비동기 코드를 동기 코드처럼 보이고 동작하도록 만들 수 있습니다. 다음은 co 라이브러리를 사용하는 예입니다.

const co = require('co');

function* fetchUserData() {
  const user = yield fetchUser();
  const posts = yield fetchPosts(user.id);
  const comments = yield fetchComments(posts[0].id);
  return { user, posts, comments };
}

co(fetchUserData).then(result => {
  console.log(result);
}).catch(error => {
  console.error(error);
});
로그인 후 복사
로그인 후 복사

이 코드는 동기식으로 보이지만 실제로는 3개의 비동기 호출을 수행하고 있습니다. 생성기는 약속이 해결될 때까지 각 산출에서 일시 중지됩니다.

발전기는 협력적인 멀티태스킹에도 사용할 수 있습니다. 여러 생성기를 생성하고 생성기 간에 전환하여 동시 실행을 시뮬레이션할 수 있습니다.

function* task1() {
  yield 'Start task 1';
  yield 'Middle of task 1';
  yield 'End task 1';
}

function* task2() {
  yield 'Start task 2';
  yield 'Middle of task 2';
  yield 'End task 2';
}

function run(tasks) {
  const iterations = tasks.map(task => task());
  while (iterations.length) {
    const [first, ...rest] = iterations;
    const { value, done } = first.next();
    if (!done) {
      console.log(value);
      iterations.push(first);
    }
    iterations.unshift(...rest);
  }
}

run([task1, task2]);
로그인 후 복사

이 코드는 두 작업을 번갈아 가며 한 번에 한 단계씩 실행합니다.

생성기는 상태 머신을 생성하는 데에도 적합합니다. 각 생산량은 서로 다른 상태를 나타낼 수 있습니다.

function* trafficLight() {
  while (true) {
    yield 'red';
    yield 'green';
    yield 'yellow';
  }
}

const light = trafficLight();
console.log(light.next().value); // red
console.log(light.next().value); // green
console.log(light.next().value); // yellow
console.log(light.next().value); // red
로그인 후 복사

이 신호등은 계속해서 해당 상태를 순환합니다.

이제 좀 더 발전된 기술에 대해 이야기해 보겠습니다. 발전기 위임을 통해 다른 발전기에 양보할 수 있습니다:

function* innerGenerator() {
  yield 'inner 1';
  yield 'inner 2';
}

function* outerGenerator() {
  yield 'outer 1';
  yield* innerGenerator();
  yield 'outer 2';
}

const gen = outerGenerator();
console.log(gen.next().value); // outer 1
console.log(gen.next().value); // inner 1
console.log(gen.next().value); // inner 2
console.log(gen.next().value); // outer 2
로그인 후 복사

yield* 구문은 innerGenerator에 위임하여 externalGenerator를 계속하기 전에 모든 값을 생성합니다.

생성기의 오류 처리도 언급할 가치가 있습니다. throw() 메서드를 사용하여 생성기에 오류를 던질 수 있습니다.

function* errorGenerator() {
  try {
    yield 'Start';
    yield 'Middle';
    yield 'End';
  } catch (error) {
    console.error('Caught:', error);
    yield 'Error handled';
  }
}

const gen = errorGenerator();
console.log(gen.next().value); // Start
console.log(gen.throw(new Error('Oops!')).value); // Caught: Error: Oops!
                                                  // Error handled
로그인 후 복사

이를 통해 매우 정교한 오류 처리 전략이 가능해졌습니다.

생성기를 사용하여 역추적 알고리즘을 구현할 수도 있습니다. 다음은 가능한 모든 항목 조합을 생성하는 간단한 예입니다.

function* countToThree() {
  yield 1;
  yield 2;
  yield 3;
}

const counter = countToThree();
console.log(counter.next().value); // 1
console.log(counter.next().value); // 2
console.log(counter.next().value); // 3
로그인 후 복사
로그인 후 복사

이 생성기는 주어진 항목의 모든 2요소 조합을 생성합니다.

생성기가 정말 빛을 발하는 분야 중 하나는 대량의 데이터를 처리하는 것입니다. 필요한 것만 계산하는 효율적인 데이터 처리 파이프라인을 만들 수 있습니다. 다음은 대용량 파일을 한 줄씩 처리하는 예입니다.

function* fibonacci() {
  let [prev, curr] = [0, 1];
  while (true) {
    yield curr;
    [prev, curr] = [curr, prev + curr];
  }
}

const fib = fibonacci();
for (let i = 0; i < 10; i++) {
  console.log(fib.next().value);
}
로그인 후 복사
로그인 후 복사

이 생성기는 파일을 한 줄씩 읽으므로 대용량 파일을 메모리에 완전히 로드하지 않고도 처리할 수 있습니다.

생성기를 사용하여 Observable 패턴을 구현할 수도 있습니다. 간단한 구현은 다음과 같습니다.

function* paginate(items, pageSize) {
  for (let i = 0; i < items.length; i += pageSize) {
    yield items.slice(i, i + pageSize);
  }
}

const allItems = Array.from({ length: 100 }, (_, i) => i + 1);
const pageSize = 10;
const pages = paginate(allItems, pageSize);

console.log(pages.next().value); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(pages.next().value); // [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
로그인 후 복사
로그인 후 복사

이 생성기는 관찰자 역할을 하며 수신한 각 데이터를 처리합니다.

제너레이터의 또 다른 멋진 용도는 사용자 정의 제어 구조를 만드는 것입니다. 다음은 생성기를 사용하는 재시도 함수의 예입니다.

const co = require('co');

function* fetchUserData() {
  const user = yield fetchUser();
  const posts = yield fetchPosts(user.id);
  const comments = yield fetchComments(posts[0].id);
  return { user, posts, comments };
}

co(fetchUserData).then(result => {
  console.log(result);
}).catch(error => {
  console.error(error);
});
로그인 후 복사
로그인 후 복사

이 재시도 기능은 포기하기 전까지 최대 maxAttempts 번까지 주어진 기능을 시도합니다.

결론적으로 생성기는 더욱 표현력이 풍부하고 효율적이며 유지 관리가 쉬운 코드를 작성하는 데 도움이 되는 JavaScript의 강력한 기능입니다. 복잡한 제어 흐름을 처리하고, 비동기 작업을 관리하고, 대규모 데이터 세트를 처리하는 데 적합합니다. 처음에는 조금 이상해 보일 수도 있지만, 일단 익숙해지면 프로젝트에서 이를 사용할 수 있는 모든 종류의 창의적인 방법을 발견하게 될 것입니다. 그럼 다음 JavaScript 프로젝트에서 생성기를 사용해 보세요. 코드를 얼마나 단순화할 수 있는지 알면 놀랄 것입니다!


우리의 창조물

저희 창작물을 꼭 확인해 보세요.

인베스터 센트럴 | 스마트리빙 | 시대와 메아리 | 수수께끼의 미스터리 | 힌두트바 | 엘리트 개발자 | JS 학교


우리는 중간에 있습니다

테크 코알라 인사이트 | Epochs & Echoes World | 투자자중앙매체 | 수수께끼 미스터리 매체 | 과학과 신기원 매체 | 현대 힌두트바

위 내용은 JavaScript 생성기: 일시 중지 기능으로 코드를 강화하세요!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿