루프를 기다리세요

12899 단어 javascriptcoding
Cover image by Dakota Ray on Flickr

최근에 JavaScript에 대한 내용을 읽었다면 JavaScript에 때때로 새로운 기능이 추가된다는 것을 이미 알고 있을 것입니다. 그 중 하나가 비동기식 반복입니다.

iterables 및 async/await에 대해 이미 알고 있을 것입니다. 하지만 걱정하지 않으셔도 됩니다. 먼저 업데이트하겠습니다.

반복 가능



IterablesSymbol.iterator 메서드가 있는 개체를 반환하는 next() 필드에 메서드가 있는 개체입니다. 이것은 해당 객체의 모든 반복 가능한 값을 얻는 데 사용할 수 있습니다.

JS 내장 객체인 배열의 경우 다음과 같습니다.

const a = [1, 2, 3];
const iteratorOfA = a[Symbol.iterator]();

iteratorOfA.next(); // { value: 1, done: false }
iteratorOfA.next(); // { value: 2, done: false }
iteratorOfA.next(); // { value: 3, done: false }
iteratorOfA.next(); // { value: undefined, done: true}



좋은 점은 추가 구문 없이 for-in-loop에서 사용할 수 있다는 것입니다.

const a = [1, 2, 3];
for(let i in a) console.log(i); 



그러나 예, 이것은 너무 끝내주는 기본 JavaScript 항목이 아닙니다.

멋진 부분은 자신의 iterable을 작성할 수 있다는 것입니다.

const iterable = {
  a: 1,
  b: 2,
  c: 3,
  d: 4,
  [Symbol.iterator]: function() {
    const keys = Object.keys(this);
    let i = 0;
    return {
      next: () => {
        if (i == keys.length) return {value: null, done: true};
        return {
          value: [keys[i], this[keys[i++]]],
          done: false
        };
      }
    }
  }
};

for(let item of iterable) console.log(item);

Object.keys()는 비기호 키만 배열로 반환하므로 Symbol.iterator는 표시되지 않습니다.

이제 반환된 객체의 다음 메서드가 호출되면 새 키와 값 쌍을 배열로 반환합니다. 더 이상 쌍을 찾지 못하면 done: true가 포함된 개체를 반환하고 호출자에게 완료되었음을 알립니다.

끝에서 볼 수 있듯이 이 새로운 객체는 for-in-loop에서 배열처럼 사용할 수 있습니다.

비동기/대기



다소 최근에 나온 그다지 기본적이지 않은 JavaScript 기능은 비동기 함수 또는 .

기본적으로 약속에 구문 설탕을 추가합니다.

async/await가 없으면 다음과 같이 보일 것입니다.

function load(url) {
  return fetch(url)
  .then(response => response.json())
  .(json => json.data);
}


그리고 다시 동기식으로 보이는 코드를 작성할 수 있습니다.

async function load(url) {
  const response = await fetch(url);
  const json = await response.json();
  return json.data;
}


비동기식 반복



상상할 수 있듯이 단 하나의 약속으로 수행되지 않는 비동기 작업이 꽤 많이 있습니다.

그러나 단순히 다음과 같이 작성할 수는 없습니다.

function processRows(filePath) {
  for(let row of getRow(filePath)) {
    ...
  }
}

getRow() 호출이 비동기 작업인 파일 시스템에 도달하기 때문입니다. 처리할 단일 행을 가져오기 전에 전체 파일을 읽어야 합니다.

또는 페이지가 매겨지는 서버 호출일 수 있으며 모든 페이지를 가져오기 위해 여러 호출을 보내야 합니다.

그러나 이제 이에 대한 proposal도 있습니다!
Symbol.iterator를 사용하고 값을 반환하는 next-method를 사용하는 대신 Symbol.asyncIterator를 사용하고 해당 값의 약속을 반환하는 next-method를 사용합니다.

const asyncIterable = {
  a: 1,
  b: 2,
  c: 3,
  d: 4,
  [Symbol.asyncIterator]: function() {
    const keys = Object.keys(this);
    let i = 0;
    return {
      next: () => {
        if (i == keys.length) return Promise.resolve({value: null, done: true});
        return Promise.resolve({
          value: [keys[i], this[keys[i++]]],
          done: false
        });
      }
    }
  }
};

async function process() { 
  for await (let item of asyncIterable) console.log(item);
}

process();



그리고 try/catch와 다른 모든 멋진 동기 기능을 뿌릴 수 있는 코드로 돌아갔습니다.

보시다시피 반복 가능한 데이터가 완료되면 done: true 개체로 확인되는 약속을 간단히 반환할 수 있습니다. 예를 들어, 서버가 더 이상 아무것도 반환하지 않을 때.

이 예에서 데이터는 메모리에 있지만 지금은 어디에서나 가져올 수 있습니다.

결론



비동기식 이터러블은 비동기식/대기식 구문을 만드는 또 다른 단계이며 JavaScript에 더 깊이 뿌리내린 약속입니다. 점점 더 동기적으로 보이도록 하여 비동기 코드 작성 작업을 용이하게 합니다.

다른 게시물에서도 언급한 대안은 observables 에서 제공하는 것과 같습니다. RxJS .

좋은 웹페이지 즐겨찾기