노드를 재구성하다.js(위)
21141 단어 javascriptcleancodenodepractices
1. 비동기식/대기 사용
따라서 자바스크립트에서 비동기 코드를 작성하는 데는 세 가지 방법이 있다. 리셋, 약속, 비동기/대기.
(만약 당신이 아직 회조지옥을 탈출하지 않았다면, 나는 당신이 다른 dev.to 문장:by)을 보길 권장합니다.
Async/await는 약속보다 더 깨끗하고 읽을 수 있는 문법으로 비동기 비저항 코드를 구축할 수 있도록 합니다👍.
다음 코드 실행
myFunction()
을 예로 들어 함수를 반환하고 함수에서 발생할 수 있는 오류를 처리합니다.// Promises
myFunction()
.then(data => {
doStuff(data);
})
.catch(err => {
handle(err);
});
// async/await
try {
const data = await myFunction();
doStuff(data);
}
catch (err) {
handle(err);
}
사용async/await
이 더 깨끗하고 읽기 쉽지 않나요?비동기식/대기 상태에 대한 추가 팁:
2. 순환 대기 방지
async/await가 매우 뚜렷하고 읽기 쉽기 때문에 우리는 이렇게 시도할 수 있습니다.
const productsToUpdate = await productModel.find({ outdated: true });
for (const key in productsToUpdate) {
const product = productsToUpdate[key];
product.outdated = false;
await product.save();
}
위의 코드는 await
로 제품 목록을 검색한 다음 그것들을 훑어보고 하나씩 업데이트합니다.이것은 효과가 있을 수 있지만, 우리는 더욱 잘 할 수 있을 것이다🤔. 다음 대안을 고려하십시오.옵션 A: 질의 작성
우리는 하나의 조회를 쉽게 작성하여 하나의 조회에서 제품을 찾고 이를 업데이트함으로써 데이터베이스에 책임을 위탁하고 N개의 조작을 1개로 줄일 수 있다.다음은 메서드입니다.
await productModel.update({ outdated: true }, {
$set: {
outdated: false
}
});
선택 B: 약속.몽땅
이 예에서는 옵션 A가 올바른 선택임이 분명하지만 비동기식 작업이 데이터베이스 작업이 아닌 외부 REST API에 대한 요청으로 병합되지 않을 경우
await Promise.all([asyncFunction1, asyncFunction2])
를 사용하여 모든 작업을 병렬적으로 실행하는 것이 좋습니다.const firstOperation = myAsyncFunction();
const secondOperation = myAsyncFunction2('test');
const thirdOperation = myAsyncFunction3(5);
await Promise.all([ firstOperation, secondOperation, thirdOperation ]);
이런 방법은 모든 비동기 함수를 실행하고 그것들이 모두 해결되기를 기다릴 것이다.조작 간에 의존 관계가 없을 때만 그것이 작용한다.3. 비동기 fs 모듈 사용
Node
find
모듈을 사용하면 파일 시스템과 상호 작용할 수 있습니다.Promise.all
모듈의 모든 동작은 동기화와 비동기화 옵션을 포함한다.다음은 파일을 읽는 비동기적이고 동기화 코드의 예이다👇
// Async
fs.readFile(path, (err, data) => {
if (err)
throw err;
callback(data);
});
// Sync
return fs.readFileSync(path);
동기화 옵션 (보통 fs
으로 끝납니다. 예를 들어 fs
) 은 리셋이 필요하지 않지만, 실제로는 프로그램의 성능을 해칠 수 있기 때문입니다.왜?동기화 작업이 막히기 때문에, 프로그램이 파일을 동기화해서 읽을 때, 다른 코드의 실행을 막을 수 있습니다.그러나 만약 우리가 다른 방법으로
Sync
모듈을 사용하고 리셋을 피할 수 있는 방법을 찾을 수 있다면 정말 좋겠다. 그렇지?다음 힌트를 보고 어떻게 사용하는지 알아보세요.4.util을 사용하여 리셋을 약속으로 전환합니다.허락
readFileSync
는 노드에서 온 함수다.jsfs
모듈.그것은 표준 리셋 구조를 따르는 함수를 받아들여 약속으로 변환한다.이것도 리셋 스타일의 함수에 사용할 수 있다promisify
.우리 예를 하나 봅시다.노드
util
모듈의 함수await
와 readFile
는 모두 리셋 구조를 따르기 때문에 access
의 비동기 함수에 사용하도록 권장합니다.다음은 콜백 버전입니다.
const fs = require('fs');
const readFile = (path, callback) => {
// Check if the path exists.
fs.stat(path, (err, stats) => {
if (err)
throw err;
// Check if the path belongs to a file.
if (!stats.isFile())
throw new Error('The path does not belong to a file');
// Read file.
fs.readFile(path, (err, data) => {
if (err)
throw err;
callback(data);
});
});
}
이것은 "promisified"+ 비동기 버전입니다👌:const util = require('util');
const fs = require('fs');
const readFilePromise = util.promisify(fs.readFile);
const statPromise = util.promisify(fs.stat);
const readFile = async (path) => {
// Check if the path exists.
const stats = await statPromise(path);
// Check if the path belongs to a file.
if (!stats.isFile())
throw new Error('The path does not belong to a file');
// Read file.
return await readFilePromise(path);
}
5. 설명 오류 유형 사용
만약에 우리가 REST API를 위해 하나의 단점을 구축하고 있는데 이 단점은 id를 통해 제품을 되돌려줍니다. 서비스는 논리를 처리하고, 컨트롤러는 요청을 처리하며, 서비스를 호출하고, 응답을 생성합니다.
/* --- product.service.js --- */
const getById = async (id) => {
const product = await productModel.findById(id);
if (!product)
throw new Error('Product not found');
return product;
}
/* --- product.controller.js --- */
const getById = async (req, res) => {
try {
const product = await productService.getById(req.params.id);
return product;
}
catch (err) {
res.status(500).json({ error: err.message });
}
}
그럼, 여기에 무슨 문제가 있습니까?만약에 저희 서비스의 첫 줄(fs
에서 데이터베이스나 네트워크 관련 오류를 던졌다면 앞의 코드에서 오류의 처리 방식은'찾지 못한'오류와 완전히 같습니다.이것은 우리 고객으로 하여금 오류를 더욱 복잡하게 처리할 것이다.그 밖에 더 큰 문제는 보안상의 이유로 클라이언트에게 어떤 오류도 돌려주고 싶지 않다는 것이다. (민감한 정보를 폭로할 수도 있다.)
우리는 어떻게 이 문제를 해결합니까?
이런 상황을 처리하는 가장 좋은 방법은 각 상황에 상응하는 오류 유형을 사용하여 실현하는 것이다.이것은 우리가 필요로 하는 모든 오류를 포함하는 라이브러리를 구축하거나 설치할 수 있습니다.
내가 애용하는 REST APIthrow.js의 경우이것은 가장 흔히 볼 수 있는 HTTP 상태 코드와 일치하는 오류를 포함하는 매우 간단한 모듈입니다.이 모듈에서 정의한 모든 오류는 상태 코드를 속성으로 포함합니다.
앞의 예제에서 사용
await
한 결과를 살펴보겠습니다./* --- product.service.js --- */
const error = require('throw.js');
const getById = async (id) => {
const product = await productModel.findById(id);
if (!product)
throw new error.NotFound('Product not found');
return product;
}
/* --- product.controller.js --- */
const error = require('throw.js');
const getById = async (req, res) => {
try {
const product = await productService.getById(req.params.id);
return product;
}
catch (err) {
if (err instanceof error.NotFound)
res.status(err.statusCode).json({ error: err.message });
else
res.status(500).json({ error: 'Unexpected error' });
}
}
두 번째 방법에서 우리는 두 가지를 실현했다.다음은 가장 흔히 볼 수 있는 오류 유형을 실현하는 또 다른 모듈이다.node-common-errors.
사상💬
이 힌트들은 쓸모가 있습니까?
다른 노드를 써달라고요?이 시리즈의 다음 글은 js와 관련된 주제입니까?
효과적/깨끗한 노드를 쓰는 기교는 무엇입니까?js 코드?
나는 너의 피드백을 듣고 싶다!
Reference
이 문제에 관하여(노드를 재구성하다.js(위)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/paulasantamaria/refactoring-node-js-part-1-42fe텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)