노드를 재구성하다.js(위)

이것은 일련의 문장의 첫 번째 부분이다. 나는 그 중에서 더욱 깨끗하고 효과적인 node를 쓰는 기교를 공유할 것이다.js 코드.

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 모듈 사용
    Nodefind 모듈을 사용하면 파일 시스템과 상호 작용할 수 있습니다.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 모듈의 함수awaitreadFile는 모두 리셋 구조를 따르기 때문에 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' });
        }
    }
    
    두 번째 방법에서 우리는 두 가지를 실현했다.
  • 저희 컨트롤러는 현재 오류를 이해하고 해당하는 행동을 취할 수 있는 충분한 정보를 가지고 있습니다.
  • REST API 클라이언트는 오류를 처리하는 데 도움이 되는 상태 코드를 받게 됩니다.
  • 우리는 심지어 모든 오류를 처리하는 전역 오류 처리 프로그램이나 중간부품을 구축함으로써 이 점을 더욱 실현할 수 있다. 그러면 우리는 컨트롤러에서 코드를 제거할 수 있다.그러나 이것은 다른 문장의 주제다.
    다음은 가장 흔히 볼 수 있는 오류 유형을 실현하는 또 다른 모듈이다.node-common-errors.

    사상💬
    이 힌트들은 쓸모가 있습니까?
    다른 노드를 써달라고요?이 시리즈의 다음 글은 js와 관련된 주제입니까?
    효과적/깨끗한 노드를 쓰는 기교는 무엇입니까?js 코드?
    나는 너의 피드백을 듣고 싶다!

    좋은 웹페이지 즐겨찾기