Giter Site home page Giter Site logo

dev-full-stack's People

Contributors

sangheon-kim avatar

Stargazers

LEE LOUN avatar KHJ avatar Seongbin Kim avatar 정윤재 avatar Heaeun avatar Byun Sang June avatar Ryu Ki-Hyeok avatar

Watchers

Byun Sang June avatar Iksu Ezra Eom avatar  avatar

Forkers

1981khj

dev-full-stack's Issues

[My Debug Note#1]-Web-Vitals 결과 통계 Object Target 서버 전송 오류 (DOM 오브젝트 서버 송신) - 해결완료

Setter도 막혀있고, DOM Element객체는 Stringify가 진행되지 않는다.

  • DOM Object에서 보낼것들만 추출해서 문자열로 만들기
const parsingFunc = (item: { [key: string]: any }, key: string) => {
    const whiteList = ["id", "tagName", "className", "outerHTML"];
    const stringObj = JSON.stringify(item[key], whiteList);
    const obj = {
      ...item,
      target: JSON.parse(stringObj),
    };

    return obj;
  };
  • Setter가 먹지 않는 부분 해결 (Proxy Trap 사용)
  const handler = {
    get(target: any, key: any) {
      if (Array.isArray(target[key])) {
        return target[key].map((item: any) => {
          if ("target" in item) {
            return parsingFunc(item, "target");
          } else if ("element" in item) {
            return parsingFunc(item, "element");
          } else {
            return item;
          }
        });
      } else {
        return target[key];
      }
    },
  };

  const proxy = new Proxy(staticObject, handler);
  const obj = deepCopy(proxy);

깔끔하게 해결된다.

[My Debug Note#2] - getTTFB, getCLS는 동작하나 getFID, getFCP, getLCP는 동작하지 않는문제 (해결완료)

build한 결과물을 압축한 vitals.zip으로 아카이브한 파일을 압축해제하여 정적파일 놓은 후

<head>
<!-- ...  -->
<!-- defer를 두어, 로드를 블로킹 하는것을 막는다. -->
<script defer src="./vitals/polyfill.js"></script>
<!-- ...  -->
</head>
<body>
<!-- ...  -->
<script defer src="./vitals/web-vitals.base.umd.js"></script>
<script>
  window.addEventListener("DOMContentLoaded", function() {
    webVitals.getCLS(console.log);
    webVitals.getFID(console.log);
    webVitals.getFCP(console.log);
    webVitals.getLCP(console.log);
    webVitals.getTTFB(console.log);
  })
</script>
</body>

[My Development Note#1] - 프로미스 직렬처리와 더불어 다음 Promise로 결과 파라미터 전달하기 - 개발완료

AsyncLib.ts

class AsyncLib {
  state: Object | { [key: string]: any };

  constructor() {
    this.state = {};
    this.constant = this.constant.bind(this);
    this.shWaterFall = this.shWaterFall.bind(this);
  }

  /**
   *
   * @description 들어오는 값으로 상태 변경
   * @param {{ [key: string]: any }} params
   * @returns
   * @author Sangheon Kim
   * @memberof AsyncLib
   */
  constant(params: { [key: string]: any }) {
    return new Promise((resolve, reject) => {
      if (Object.keys.length > 0) {
        // params로 사용할 객체가 넘어왔다면 인스턴스의 state를 초기화 해주고,
        // success Resolve 해준다.
        this.state = params;
        resolve("Success");
      } else {
        // 파라미터로 온것이 객체타입이 아니거나, 전달받은게 없는 경우에 reject 해준다.
        reject("No params");
      }
    });
  }

  /**
   *
   * @description 순차적으로 들어온 콜백 리스트들을 실행 후 세번째 매개변수로 넘어온 callback 함수를 실행시켜주어 결과 반환
   * @param {{ [key: string]: any }} initial
   * @param {Array<(params?: any) => any>} callbackArray
   * @param {*} [cb] (err, result) 이렇게 두가지의 매개변수를 전달받을 콜백을 넣어주면된다.
   * @memberof AsyncLib
   */
  shWaterFall(
    initial: { [key: string]: any },
    callbackArray: Array<(params?: any) => any>,
    cb?: any
  ) {
    /**
     * @description 콜백 함수 리스트를 전달받아서 순차적으로 실행
     */
    const g: Generator = function* (this: AsyncLib) {
      this.constant(initial); // shWaterfall의 첫번째 인수로 전달받은 초기값을 기반으로 state초기화
      for (let callback of callbackArray) {
        // callbackArray는 결국 Array 형태이기에 이터레이션 프로토콜을 준수하고 있기에 for...of 사용 가능
        yield (async (
          genObj: Generator,
          promise: (params?: { [key: string]: any }) => Promise<any>
        ) => {
          // 첫번째 매개변수로는 자기자신 제너레이터를 전달받고, 두번째 매개변수로 promise 함수를 전달받는다. callbackArray가 끝나면 결국 이터레이터는 종료
          try {
            // promise 결과값을 result 변수에 할당
            const result = await promise(this.state);
            // 결과값을 인스턴스의 state에 할당해준다.
            this.state = result;
            // 그리고 결과값을 다음 콜백함수의 파라미터로 넘겨준다.
            genObj.next(result);
          } catch (err) {
            console.log("errorZZz", err);
            // 에러시에는 첫번째 인수에 err를 전달하여 에러에 대한 응답 반환을 처리한다.
            return cb(err, null);
          }
        })(g, callback); // IIFE이기에 매개변수를 직접 내가 할당해주었다. 제너레이터함수는 호출하면 제너레이터를 반환
      }
      // 에러없이 정상적으로 실행되었을 경우에 현재 파라미터에는 모든 콜백을 돌고돌아 오버라이딩되고 추가된 파라미터들이 담긴 결과 object가 있을 것이다.
      // 이걸 전달받은 콜백함수의 두번째 인수로 전달해준다.
      return cb(null, this.state);
    }.call(new AsyncLib()); // this에 AsyncLib을 넣어주어 State 참조하게 만든다.

    // 초기에는 한번 정적으로 실행해준 코드를 넣어주었다. 어짜피 처음 제너레이터 오브젝트의 next메소드에는 아무것도 전달할 수 없다.
    g.next();
  }
}

// 생성자 함수를 사용하여 instance를 내보내준다.
export default new AsyncLib();

Usage Example

import { Request, Response } from "express";
import jwt from "jsonwebtoken";
import { jwtSecret } from "../app";
import AuthService from "../services/AuthService2";
import ValidationParams from "../utils/validationParams";
import { makeSucessedResponse, makeErrorResponse } from "../utils";
import async from "../utils/asyncLib";

class AuthController {
  constructor() {
    this.join = this.join.bind(this);
  }

  /**
   *
   * @description 로그인 관련 컨트롤러
   * @date 2020-12-11
   * @param {Request} req
   * @param {Response} res
   * @memberof AuthController
   */
  async login(req: Request, res: Response) {
    const makeResponse = (err: null | Error, data: null | any) => {
      if (err) {
        makeErrorResponse({ res, err });
        return;
      }
      const token = jwt.sign({ sub: data.id }, jwtSecret);
      const params = {
        ...data["result"],
        accessToken: token,
      };
      makeSucessedResponse({
        res,
        data: params,
        cookie: { accessToken: token, option: { maxAge: 90000, httpOnly: true } },
      });
    };

    async.shWaterFall(
      req.body,
      [
        ValidationParams.validParams,
        ValidationParams.validEmail,
        AuthService.hashPassword,
        AuthService.matchUser,
      ],
      makeResponse
    );
  }

  /**
   *
   * @description 회원가입 관련 컨트롤러
   * @date 2020-12-09
   * @author Sangheon Kim
   * @param {Request} req
   * @param {Response} res
   * @memberof AuthController
   */
  async join(req: Request, res: Response) {
    const makeResponse = (err: null | Error, __: any) => {
      if (err) {
        makeErrorResponse({ res, err });
        return;
      }

      makeSucessedResponse({ res });
    };

    async.shWaterFall(
      req.body,
      [
        ValidationParams.validParams,
        ValidationParams.validEmail,
        AuthService.emailDuplicateCheck,
        AuthService.hashPassword,
        AuthService.createUser,
      ],
      makeResponse
    );
  }
}

export default new AuthController();

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.