회원 가입 폼 - 밸리데이션 구조 설계

 

밸리데이션 체크

 

회원 가입 폼을 만들면서 각 필드의 유효성을 체크하는 항목이 필요하다. 최소 몇 글자여야하는지, 대문자인지 소문자인지, 숫자로 시작하는지 등의 유효성 체크를 하는데 있어 if~else 문을 통해 여러가지의 항목들을 체크할 수도 있지만 이러한 코드는 어떻게 기능을 구현을 해놓는다 한들 유지보수를 하거나 또 다른 기능이 추가될 시에 비용이 배로들거나 기능 구현에 어려움이 생길것이다.

 

그렇기 때문에 정규식(RegExp)을 사용한다.

(types/common.ts)

export type ValidateRule = {
  rule: RegExp;
  match: boolean;
  message: string;
}

types 폴더에 common.ts 파일에 있는 정규식에 관한 타입을 정의한 부분이다. ValidateRule은 rule에 정규식을 입력받고 match를 통해 해당 정규식과 문자열의 true/false 체크를 할 것이며, message는 정규식의 결과를 틀리거나 맞았을 때, 그에 대한 사용자에게 전달할 설명을 갖는다.

 

 

(constant.ts)

import { ValidateRule } from "./types";

export const RequireRule: ValidateRule = {
  rule: /.+/,
  match: true,
  message: '필수 입력 항목입니다.',
};

export const CantContainWhitespace: ValidateRule = {
  rule: /\s/,
  match: false,
  message: '공백을 포함할 수 없습니다.',
};

export const CantStartNumber: ValidateRule = {
  rule: /^\d/,
  match: false,
  message: '숫자로 시작하는 아이디는 사용할 수 없습니다.',
}

export const MinimumLengthLimit = (limit: number): ValidateRule => ({
  rule: new RegExp(`(.){${limit}}`),
  match: true,
  message: `최소한 ${limit}글자 이상 이어야 합니다.`,
});

constant.ts 파일엔 ValidateRule의 타입을 기반한 각각의 정규식들을 가지고 있다.

RequireRule ".+" => "."은 \를 제외한 모든 문자를 의미하며 "+"는 1개 이상의 문자가 나올 수 있다는 것을 의미한다.

CantContainWhitespace "\s" => "\s"는 공백을 의미한다. 반대로 "\S"는 반대로 공백을 아닌것을 의미한다.CantStartNumber "^\d" => "^"는 첫번째의 문자를 의미하며 "\d"는 모든 숫자를 의미한다.MinimumLengthLimit "`(.){숫자}`" => ()는 문자열을 하나로 인식하며, "."은 \를 제외한 모든 문자이며 {}안에 있는 숫자는 최소한의 숫자 값을 의미한다.

 

 

 

 

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #김민태의프론트엔드아카데미:제1강JavaScript&TypeScriptEssential

회원 가입 폼 - 밸리데이션 구조 설계

 

views 폴더의 text-field.ts 구조

 

text-field는 아마 회원 가입 폼에서 가장 많이 사용하게되는 항목일 것이다. text-field.ts 파일의 구조를 알아보겠다.

 

import { nextTick } from '../utils';
import { ValidateRule } from '../types';
import template from './text-field.template';
import { RequireRule } from '../constant';

type Props = {
  id: string;
  label: string;
  type: 'text' | 'email' | 'number';
  placeholder?: string;
  text?: string;
  require: boolean;
}

const DefaultProps: Props = {
  id: '',
  text: '',
  label: 'label',
  type: 'text',
  placeholder: '',
  require: false,
};

export default class TextField {
  private template = template;
  private container: string;
  private data: Props;  
  private updated: boolean = false;
  private validateRules: ValidateRule[] = [];

  constructor(container: string, data: Props) {
    this.container = container;
    this.data = { ...DefaultProps, ...data };

    if (this.data.require) {
      this.addValidateRule(RequireRule);
    }

    nextTick(this.attachEventHandler);
  }

  private validate = (): ValidateRule | null => {
    ...
  }

  private buildData = () => {
    ...
  }

  private onChange = (e: Event) => {
    ...
  }

  private attachEventHandler = () => {
    ...
  }

  private update = () => {
    ...
  }

  public get name(): string {
    return this.data.id;
  }

  public get value(): string {
    ...
  }

  public get isValid(): boolean {
    ...
  }

  public addValidateRule = (rule:ValidateRule) => {
    ...
  }

  public render = (append: boolean = false) => {
    const container = document.querySelector(this.container) as HTMLElement;

    if (append) {
      const divFragment = document.createElement('div');
      divFragment.innerHTML = this.template(this.buildData());

      container.appendChild(divFragment.children[0]);
    } else {
      container.innerHTML = this.template(this.buildData());
    }
  }
}

 

text-filed.ts에도 많은 메소드들이 있지만 먼저 웹앱의 화면이 변화되는 구조를 먼저 보면, 여기도 app.ts 파일과 마찬가지로 render 함수를 통해서 변경된다.

 

차례대로 살펴보면 data에 사용될 props 타입을 정의했고, DefaultProps 변수에 아무런 데이터가 입력되지 않았을 시에 기본값으로 설정될 프로퍼티들을 정의했다.

 

TextField 클래스를 보면 app.ts와 마찬가지로 template을 사용하고 container를 통해 컨테이너가 될 엘리먼트의 아이디나 클래스 값을 정의한다. Props 타입으로 정의했던 데이터를 정의한 data필드와 update 유무체크하는 updated 변수, 유효성을 체크하는 validateRules 필드를 정의한다.

 

또한 TextField 클래스의 render 메소드에는 append라는 boolean 타입의 파라미터를 받아오는데 app.ts 와는 다르게 회원 가입 폼의 각 필드들은 innerHTML만을 사용하게되면 하나의 필드를 입력하고 다른 필드를 입력했을 시에 다른 필드를 덮어쓰게 된다. append 파라미터는 boolean 타입으로 해당하는 필드가 있을 시에 새로운 div를 생성하여 하단에 추가하는 형태로 기능을 만들것인지 아니면 기존의 필드를 새로 덮어쓰기 하여 생성할 것인지 체크하는 기능을 하게 될것이다.

 

 

 

 

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #김민태의프론트엔드아카데미:제1강JavaScript&TypeScriptEssential

회원 가입 폼 - 밸리데이션 구조 설계

 

app.ts의 전체적인 구조

 

import template from './app.template';
import { CantContainWhitespace, CantStartNumber, MinimumLengthLimit } from './constant';
import { AnyObject } from './types';
import { TextField, PasswordField, AddressField } from './views';

export default class App {
  template = template;
  data: AnyObject;
  container: HTMLElement;
  fields: AnyObject[];
  active: boolean = false;

  constructor(container: string, data: AnyObject = {}) {
    this.container = document.querySelector(container) as HTMLElement;
    this.data = data;
    this.fields = [];

    this.initialize();
    
    setInterval(this.validFieldMonitor, 1000/30);
  }

  private initialize = () => {
    const nameField = new TextField('#required-fields', { 
      id: 'name', label: '이름', type: 'text', placeholder: '이름을 입력해주세요', require: true,
    });

    const idField = new TextField('#required-fields', { 
      id: 'id', label: '아이디', type: 'text', placeholder: '아이디를 입력해주세요', require: true,
    });

    const emailField = new TextField('#required-fields', { 
      id: 'email', label: '이메일', type: 'email', placeholder: '이메일을 입력해주세요', require: true,
    });
    
    const passwordField = new PasswordField('#required-fields', { 
      id: 'password', label: '비밀번호', placeholder: '비밀번호를 입력해주세요', 
    });

    const addressField = new AddressField('#optional-fields', {
      id: 'address', label: '배송지 주소',
    });

    idField.addValidateRule(CantContainWhitespace);
    idField.addValidateRule(CantStartNumber);
    idField.addValidateRule(MinimumLengthLimit(3));

    emailField.addValidateRule(CantContainWhitespace);

    this.fields.push(nameField);
    this.fields.push(idField);
    this.fields.push(emailField);
    this.fields.push(passwordField);
    this.fields.push(addressField);
  }

  private validFieldMonitor = () => {
    const btnJoin = this.container.querySelector('#btn-join') as HTMLButtonElement;

    if (this.fields.filter(field => field.isValid).length === this.fields.length) {
      this.active = true;
      btnJoin.classList.remove('bg-gray-300');
      btnJoin.classList.add('bg-green-500');
    } else {
      this.active = false;
      btnJoin.classList.remove('bg-green-500');
      btnJoin.classList.add('bg-gray-300');
    }
  }

  private onSubmit = (e: Event) => {
    e.preventDefault();

    if (!this.active) return;

    const submitData: AnyObject = this.fields
        .map(field => ({ [field.name]: field.value }))
        .reduce((a, b) => ({ ...a, ...b }), {});

    console.log(submitData);
  }

  public render = () => {
    this.container.innerHTML = this.template(this.data);
    this.fields.forEach(field => {
      field.render(true);
    });

    this.container.addEventListener('submit', this.onSubmit);
  }
}

app.ts는 각 views에서 가져온 text, password, address 필드의 변경된 사항이나 밸리데이션 구조 등을 전체적으로 취합해서 화면을 렌더링한다.

 

구조를 보면 기본적으로, 화면의 구조적인 UI를 가지고있는 template(app.template.ts), 각 컴포넌트에 해당하는 데이터를 가진 AnyObject를 반환하는 data와 filelds, 최상위 컨테이너를 지정하는 container, 회원가입 시 궁극적인 유효성 체크를 진행하는 active 필드 등이 있다.

 

또한 메소드 initialize()는 초기 화면을 구동했을 시에 사용하는 필드와 해당하는 필드에 들어가는 데이터 등을 인스턴스로 생성한다. validFiledMonitor()은 화면에 있는 모든 필드의 입력과 밸리데이션을 충족 했을 시에 회원 가입을 진행하는데, 모든 조건이 충족되어있는가를 체크하는 메소드이며 onSubmit()은 vaildFieldMonitor()에서 모든 조건을 충족했을 시 회원 가입을 진행할 수 있다. render()는 위이 모든 기능들의 변경에 따라 보여지는 데이터나 UI 등이 변경된다.

 

 

 

 

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #김민태의프론트엔드아카데미:제1강JavaScript&TypeScriptEssential

회원 가입 폼 - 밸리데이션 구조 설계

 

회원 가입 폼 웹앱은 index.ts 파일에 app.render() 메소드를 통해 app.ts에 정의 되어있는 기능들의 렌더링이 일어난다는것을 알게 되었다. app.ts 에 웹앱을 이루는 모든 파일들이 정의되어 있기 때문에 폴더 구조를 토대로 사용되는 파일들을 알아볼 것이다.

 

- types 폴더 - address.ts - common.ts - index.ts - user.ts

 

회원 가입 웹앱에 사용되는 타입들을 모아 놓은 폴더이다.

 

(address.ts)

export type Address = {
  zip: string;
  address1: string;
  address2: string | '';
};

export type DaumAddress = {
  address: string;
  autoJibunAddress: string;
  roadAddress: string;
  sigunguCode: string;  
}

회원 가입 폼에 있는 주소 입력창에 대한 타입 정의이다. 회원 가입 폼에 입력 하는 주소 형태의 타입과 웹앱에서 사용되는 주소에 다음 지도 API에서 가져오는 데이터 타입의 구조를 정의 해놓은 파일이다.

 

(common.ts)

export type AnyObject = {
  [key: string]: any;
}

export type ValidateRule = {
  rule: RegExp;
  match: boolean;
  message: string;
}

AnyObject는 웹앱에서 사용되는 object로 사용되는 데이터 타입을 정의했다. 어떤 데이터 타입이 올지 모르게때문에 오브젝트 형태로 받아올 수 있도록 정의했고 ValidateRule은 벨리데이션 구조를 정의하는 타입으로 지정했다.

 

(index.ts)

export * from './common';
export * from './address';
export { default as User }  from './user';

type을 정의한 types 폴더에 각 파일들을 사용하는 파일에서 한번에 import하여 사용하기 편하도록 export를 모아놓은 파일이다.

 

(user.ts)

import { Address } from './address';

type User = {
  name: string;
  id: string;
  email: string;
  password: string;
  address?: Address;
};

export default User;

회원 가입의 User에서 사용되는 타입을 정의 해놓은 파일이다. 이름, 아이디, 이메일, 비밀번호 등을 받고 주소의 경우는 address.ts에서 import 해오며 옵션 형태로 입력을 받거나 안받을 수 있는 형태이다.

 

 

 

 

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #김민태의프론트엔드아카데미:제1강JavaScript&TypeScriptEssential

회원 가입 폼 - 밸리데이션 구조 설계

 

지난번까지 회원 가입 폼의 전체적인 구조를 알아봤다. 앞으로는 동작의 순서대로 하나하나 파일의 진행 순서와 기능에 대해 순차적으로 동작을 파악한다.

 

index.html에 대표적으로 script 태그에 삽입되는 파일은 index.ts 파일인데 index.ts 파일은 글로벌로 설정되는 것들과 App 오브젝트의 인스턴스를 생성하고 render 라는 메소드를 실행했다.

 

import { AnyObject } from './types';
import App from './app';

declare global {
  interface Window {
    Handlebars: {
      compile: (template: string) => (data: AnyObject) => string;
    },
    daum: any,
  }
}

const app = new App('#root', {
  title: 'Javascript & TypeScript Essential Chapter 5 - Sign up'
});

app.render();

위 코드에서 AnyObject와 App을 import 했다. AnyObject는 시맨틱처럼 웹앱에서 사용되는 어느 오브젝트이건 해당하는 오브젝트를 포함하는 타입을 지정한 것이다. App은 index.ts 파일에서의 작업을 거쳐서 app이라는 인스턴스를 생성하고 render 메소드를 실행한다. 여기서 app 인스턴스는 생성자함수로 root라는 문자열과 title이라는 key와 문자열 value를 가진 오브젝트를 파라미터로 전달한다.

 

여기서 root는 index.html에 root라는 아이디를 가진 태그에 사용될 것, title에 "Javascript & TypeScript Essential Chapter 5 - Sign up" 문자열을 반환 한다는 것을 예상할 수 있다. 또 app 인스턴스의 메소드로 render 함수를 실행하는데, 렌더링 한다는 것을 알수는 있지만 어떤 작업을 하는지 어느 부분을 렌더링하는지 등의 상세한 작업을 알 필요는 없다. 다만 index.ts 파일에서는 app 인스턴스를 생성하고 render 함수를 실행하는 작업을 한다.

 

 

 

 

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #김민태의프론트엔드아카데미:제1강JavaScript&TypeScriptEssential

회원 가입 폼 - 밸리데이션 구조 설계

 

지금까지 작업한 결과물에 해커뉴스에 관련된 하나의 웹앱을 만들었다. 지금까지 만든 웹앱의 구조는 API형태로 데이터를 받아오고 그 데이터를 SPA 형식으로 화면에 나타내는 형태였다.

 

이번 장에서는 데이터를 받아와서 출력하는 형태 뿐아니라 데이터를 입력하고 전송하는것과 밸리데이션 체크를 하는것까지의 구조이다. 기존에 만들었던 화면보다 세세한 부분에서 렌더링이 일어나기 때문에 폴더의 구조는 좀 더 복잡해진다.

src
  |- types
    - address.ts
    - common.ts
    - index.ts
    - user.ts
  |- utils
    - index.ts
  |- views
    - address-field.template.ts
    - address-field.ts
    - index.ts
    - password-field.template.ts
    - password-field.template.ts
    - address-field.template.ts
    - address-field.template.ts
  - app.template.ts
  - app.ts
  - constant.ts
  - index.ts

 

src 하위의 폴더 구조는 이렇다. index.html에서 최상위의 index.ts 파일을 기준으로 둔다. index.ts 파일에선 전역적으로 사용하는 부분과 app.ts에 있는 사항들을 렌더링한다. app.ts는 회원가입 웹앱에 초기화하거나 사용되는 밸리데이션 등을 정의하고 입력한 사항들이 전송됐을 시에 발생하는 이벤트 등이 정의되어 있다.

views 폴더에 있는 각 파일등은 입력한 사항들의 화면과 구조 등이 있으며, types 폴더에는 각 기능들의 타입이 정의 되어있다. utils 폴더에는 유틸리티성 파일, 여러 방면에 사용될 수 있는 파일을 정의한다.

 

 

 

 

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #김민태의프론트엔드아카데미:제1강JavaScript&TypeScriptEssential

라이프 사이클과 스코프

 

스코프는 하나의 그룹핑 되어있는 영역을 말하며 라이프 사이클은 어떠한 영역 안에서 실행되고 그 영역을 벗어나게 되면 삭제되는 형태를 말한다. 스코프는 전역 스코프, 블록 스코프, 함수 등이 있으며 함수 또한 fucntion(){} 형태의 스코프 안에서 동작하고 함수 실행이 끝나고 다른 영역으로 넘어갔을 때 사라지게 된다.

 

스코프, 예를 들어, 함수가 여러개 있다고해서 메모리에 모든 함수가 등록되는 것이 아니다. 선언되어 있는 모든 스코프가 메모리에 올라갈 수는 없다. 메모리는 한정 되어있는 자원이기 때문에 효율적으로 사용할 수 있어야 한다. 스코프는 그러한 것들을 유동적으로 이용하고 있는 셈이다.

 

let myname = 'kim'; // 전역 스코프

function foo() { 
    let x = 10;

    console.log(myname);
    console.log(x);

    bar();
    zoo();

    function bar(){
        let y = 10;

        console.log(x);
        console.log(myname);
    } // foo 함수 스코프

    const zoo = function(){

    }

    if(x ===10){ // foo 스코프의 변수 x
        let x = 100; // foo 스코프 내의 if문 블록 안의 변수 x

        console.log(x);
    } // foo 함수 스코프 

    bar();
} // 전역 스코프

foo();
console.log(x);

 

스코프는 처음 진입될 때 생성된다. foo 함수로 진입 할 때, myname이라는 변수는 전역 스코프에 있으며, foo함수 내의 x라는 변수는 foo 함수의 스코프안에서 저장된다. 따라서 foo 함수에서는 myname 변수를 사용할 수 있지만 foo 함수가 실행되는 부분(전역 스코프)에서는 foo함수 안의 x를 사용할 수 없다. 스코프에서는 중첩이 일어나기 때문에 foo 함수 안에 bar 함수를 선언하면 bar 함수는 전역스코프와 foo함수 스코프 안에 있는 변수들을 사용할 수 있다. 

 

또한 함수 선언문(function xxx(){})으로 작성된 함수는 호이스팅으로 인해 실행보다 선언이 코드 아래에 있어도 사용할 수 있지만 함수 표현식(var xxx = function(){})으로 작성된 함수는 꼭 함수가 선언되고 나서 실행되어야 한다.

 

 

 

 

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #김민태의프론트엔드아카데미:제1강JavaScript&TypeScriptEssential

비동기 함수

 

4장까지 작업한 해커뉴스 클라이언트의 마지막은 데이터를 가져오는 부분에서 API를 통해 서버에서 가져오기 때문에 비동기처리를 해야했다.

 

비동기 처리를 하기위해 비동기 함수를 사용했는데 callback 함수를 사용하거나 Promise를 반환하는 Promise 패턴을 사용했다.

 

그 중에서 Promise 함수를 리턴하는 함수와 Promise를 then()~catch()나 async & await을 통해 사용하는 방법이 있다.

 

function delay(ms:number) : Promise<string> {
    return new Promise<string>((resolve, reject) => {
        setTimeout(() => {
            if(Math.floor(Math.random() *10) % 2 ===0){
                resolve('success');
            } else {
                reject('failure');;
            }
        }, ms);
    });
}

delay(3000)
    .then((result: string) =>{
        console.log('done promise' + result);
    })
    .catch((error: string) =>{
        console.error('fail promise!' + error);
    });

async function main(){
    try{
        console.log('start job')
        const result = await delay(3000);
        console.error('done async!' + result);
    } catch(e) {
        console.error('fail async' + e);
    }
}

main();

delay라는 함수를 선언하고 이 함수는 Promise를 리턴한다. Promise 패턴의 함수에는 2가지의 파라미터를 받아올 수 있는데 성공, 실패이며, 여느 callback 함수와 다른건 이 부분이다. 처리가 성공했을 시 작업과 실패했을 시의 처리를 다르게 할 수 있다.

 

위 코드에서 then()~catch()패턴에서는 성공했을 시(resolve)에 'success' 문자열을 파라미터로 받아서 사용할 수 있으며 실패했을 시(reject)에 'failure' 문자열을 파라미터로 받아서 사용할 수 있다. 꼭 문자열 뿐만이 아니더라도 콜백함수로 성공과 실패의 반환값을 넘긴다면 해당하는 패턴에서 사용할 수 있다. 성공시에 then()을 리턴하고 then()에서 또 다음의 처리를 진행하고 싶다면 return을 통해 다음 작업을 같은 방식으로 진행한다. 그렇다면 이전의 then()에서 넘긴 return 값을 then()의 파라미터로 받아서 사용할 수 있다. 이 이유는 then()에서 반환한 값은 또 Promise를 리턴하기 때문이다.

 

또 Promise를 반환하는 패턴이라면 async & await으로 사용할 수 있는데 then()~catch()와 다른 점은 해당하는 코드의 진행을 동기적으로 처리할 수 있다는 점이다. then()~catch()의 경우는 then()의 처리가 완료되고 다음의 처리를 하기위해 then()을 연속적으로 붙여서 사용해야 하는데 async & await의 경우는 async로 선언된 함수 안에 await이 명시되어 있는 함수의 다음 코드의 진행은 동기적으로 작성해도 비동기로 처리된다.

 

 

 

 

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #김민태의프론트엔드아카데미:제1강JavaScript&TypeScriptEssential

+ Recent posts