일반적인 Reduce 방법을 사용하여 TypeScript 배열을 블록으로 분할

20965 단어 typescriptnode
노드와 동시에 너무 많은 비동기 프로세스를 실행합니다.js가 프로세스를 붕괴시킬 수 있습니다.이 방면의 한 예는 비동기 리셋 함수의 파일을 읽을 때 이 함수는 수조의 map() method 를 사용하여 실행되고 있다는 것이다.노드를 방지합니다.js 프로세스는 EMFILE error로 인해 붕괴될 수 있습니다. 하나의 그룹을 비교적 작은 그룹이나 블록으로 나누고, 비교적 작은 그룹을 동기화하며, 각 작은 그룹의 항목을 비동기적으로 비추는 것이 도움이 될 수 있습니다.이렇게 하면 원시 그룹의 내용을 일괄적으로 처리하여 너무 많은 파일을 동시에 열어서 발생하는 오류를 방지할 수 있다.다음 구성에서는 EMFILE 오류를 시연한 다음 코드를 추가하여 배열을 블록으로 분할하고 프로세스를 일괄 처리하며 오류를 방지합니다.

노드를 설치합니다.js와 npm 패키지.json
이러한 단계를 수행하기 전에 node.jsnpm가 설치되어 있는지 확인합니다.npm init 명령을 실행하고 프롬프트에 따라 패키지를 만듭니다.json 파일.소포를 받으면json 파일을 만들 때 다음 설정을 추가합니다.
{
  "type": "module"
}
코드ECMAScript modules, 특히 npm 패키지es module imports를 사용할 수 있습니다.이후에 TypeScript를 설치해야 하기 때문에 npm install TypeScript--save 명령을 실행하고 npm install@types/node--save-dev 명령을 실행합니다. 이 점에'start'라는 새 스크립트 속성을 추가해야 합니다initiate the TypeScript compiler and run the JavaScript output with Node.js.
소포.json 파일은 다음과 유사해야 합니다.
{
  "type": "module",
  "name": "splitarrayintochunks",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "tsc && node index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/node": "^14.14.22"
  },
  "dependencies": {
    "typescript": "^4.1.3"
  }
}

유형 설정 스크립트
노드를 구성한 후js, tsconfig를 추가합니다.json 파일은 가방과 같은 폴더에 저장됩니다.json 파일.이를 통해 JavaScript 대신 방금 설치한 TypeScript를 사용할 수 있으므로 다른 기능generic types에서 이점을 얻을 수 있습니다.이 설정을 tsconfig에 복사합니다.json 파일:
{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "isolatedModules": true,
    "strict": true,
    "module": "esnext",
    "lib": ["ES2019"],
    "moduleResolution": "node",
    "skipLibCheck": true
  },
  "include": ["*.ts"],
  "exclude": ["node_modules/**/*"]
}
tsconfig "module"필드에 표시된 TypeScript 컴파일된 출력은 패키지에 추가된 유형 필드와 일치하는 ECMAScript 모듈로 생성됩니다.json 설정.

노드파일을 읽는 동안 js EMFILE 오류가 발생했습니다.
구성 단계가 완료되었으므로 EMFILE 오류를 보여주는 코드를 추가할 수 있으며 작은 블록에서 배열을 일괄 처리하여 오류를 방지할 수 있습니다.오류를 일으킨 예시 코드를 색인에 추가할 수 있습니다.ts.
import fs from "fs";
import util from "util";
const readFile = util.promisify(fs.readFile);

(async function main() {
  //an array containing ten thousand undefined items
  const originalArray = Array.from(Array(10000));

  try {
    // awaiting all ten thousand promises simultaneously
    await Promise.all(
      originalArray.map(async () => {
        const file = await readFile("./data.json", "utf8");
        console.log(file);
      })
    );
  } catch (error) {
    console.log(error);
  }
})();
이 때 '데이터. json' 이라는 예시 파일 JSON 을 만들어야 합니다.이 파일에 추가할 모든 내용은 "{}"이며 빈 JSON 대상으로 해석됩니다.데이터 파일을 만든 후 npm run start 명령을 실행하면 콘솔에서 오류가 발생할 수 있습니다.
[Error: EMFILE: too many open files, open '/../../data.json'] {
  errno: -4066,
  code: 'EMFILE',
  syscall: 'open',
  path: '/../../data.json'
}
우리는 비동기적으로 데이터를 읽으려고 시도하고 있다.json 파일이 한 번에 만 번 실행되는데, 오류는 코드가 실행되는 시스템이 너무 많다는 것을 알려주는 것입니다. file descriptors데이터에 대한 액세스.json 파일이 발생하는 빈도가 너무 높아서 시스템이 추적할 수 없어서 프로세스가 붕괴되었습니다.
모든 만 번의 파일 읽기 시도를 한 번에 시도하기보다는 그룹을 블록으로 나누고 읽기 요청을 대량으로 처리하여 파일 설명자의 총수가 이 노드 시스템의 적당한 제한 범위 내에 있는지 확인하십시오.js 수술 중입니다.이를 위해 모든 유형의 배열을 원래 배열 유형의 블록으로 분할하는 일반적인 TypeScript 함수를 만들 수 있습니다.

TypeScript 일반 감속기가 배열을 블록으로 분할
색인에 있습니다.즉시 호출된 주 함수 위에 'chunkItems' 라는 함수를 만들 수 있습니다.이렇게 하면 TypeScript 범주를 사용하여 원래 배열 유형과 일치하는 작은 배열 그룹을 포함하는 배열이 만들어집니다.
const chunkItems = <T>(items: T[]) =>
  items.reduce((chunks: T[][], item: T, index) => {
    const chunk = Math.floor(index / 512);
    chunks[chunk] = ([] as T[]).concat(chunks[chunk] || [], item);
    return chunks;
  }, []);
reduce() method는 소수점 블록을 포함하는 그룹을 만드는 데 사용되며, 이 예에서 블록 크기는 블록당 512개 항목의 제한으로 설정됩니다.이렇게 하면 한 번에 할당할 수 있는 최대 파일 설명자 수가 대부분의 시스템의 기본 제한보다 적습니다.현재, 우리는 일반적인 'chunkItems' 함수를 사용하여 일괄 처리 과정을 만들 수 있습니다. 방법은 기존의 파일 읽기 코드를 for...of loop 파일에 포장하여 각각의 Promise.all() 결과를 다른 방식으로 기다리도록 하는 것입니다.
모든 코드를 색인에 넣습니다.ts 파일은 다음과 같습니다.
import fs from "fs";
import util from "util";
const readFile = util.promisify(fs.readFile);

const chunkItems = <T>(items: T[]) =>
  items.reduce((chunks: T[][], item: T, index) => {
    const chunk = Math.floor(index / 512);
    chunks[chunk] = ([] as T[]).concat(chunks[chunk] || [], item);
    return chunks;
  }, []);

(async function main() {
  const originalArray = Array.from(Array(10000));
  const chunks = chunkItems(originalArray);
  try {
    for (const chunk of chunks)
      await Promise.all(
        chunk.map(async (item, index) => {
          const file = await readFile("./data.json", "utf8");
          console.log("-----start item------");
          console.log("current array chunk:" + chunks.indexOf(chunk));
          console.log("file contents: " + file);
          console.log("current item index: " + index);
          console.log("-----end item-------");
        })
      );
  } catch (error) {
    console.log(error);
  }
})();
npm Run start 명령을 다시 실행하면 EMFILE 오류가 발생하지 않습니다.위 코드의 출력은 상당히 빨리 표시되지만, 현재 동기화 처리 중인 모든 블록의 인덱스와 견본 데이터의 내용을 보여 줍니다.json 파일.자세히 관찰(또는 출력이 일정 시간 실행된 후에 출력을 정지)하면 블록 인덱스는 숫자 순서로 진행되지만 의도적으로 제한된 파일의 읽기 횟수는 비동기적으로 진행되고 현재 항목의 인덱스는 숫자 순서로 진행되지 않는다는 것을 알 수 있다.배열을 더 작은 블록으로 분할하면 시스템이 과부하되거나 노드가 손실되지 않습니다.js는 파일을 비동기적으로 처리할 수 있습니다.

좋은 웹페이지 즐겨찾기