<Sequential Request>

: 코드의 순서에 따라 진행

async function get3Pokemon() {
	// 순서에 따라서 코드진행 
	// they are independent lines
	const poke1 = await axios.get('http://pokeapi.co/api/v2/pokemon/1');
	// poke1 is a value(response) here, not a promise
	const poke2 = await axios.get('http://pokeapi.co/api/v2/pokemon/2');
	const poke3 = await axios.get('http://pokeapi.co/api/v2/pokemon/3');
	console.log(poke1.data);
	console.log(poke2.data);
	console.log(poke3.data);
}
get3Pokemon();

 

 

 

<Parallel Request의 옳지 않은 예시>

- 세개의 데이터 모두 undefine으로 출력된다.

async function get3Pokemon() {
	// poke1 IS a promise here
	const poke1 = axios.get('http://pokeapi.co/api/v2/pokemon/1');
	const poke2 = axios.get('http://pokeapi.co/api/v2/pokemon/2');
	const poke3 = axios.get('http://pokeapi.co/api/v2/pokemon/3');
	await poke1;
	await poke2;
	await poke3;
	console.log(poke1.data);//undefine
	console.log(poke2.data);//undefine
	console.log(poke3.data);//undefine
}
get3Pokemon();

 

 

 

<Parallel Request>

- 각각의 리퀘스트를 변수로 지정해 await를 걸어줌. 데이터 출력 확인 가능

async function get3Pokemon() {

	const prom1 = axios.get('http://pokeapi.co/api/v2/pokemon/1');
	const prom2 = axios.get('http://pokeapi.co/api/v2/pokemon/2');
	const prom3 = axios.get('http://pokeapi.co/api/v2/pokemon/3');
	const poke1 = await prom1;
	const poke2 = await prom2;
	const poke3 = await prom3;
	console.log(poke1.data);
	console.log(poke2.data);
	console.log(poke3.data);
}
get3Pokemon();

 

 

 

<Promise.all을 이용한 Parallel Request>

- 변수를 지정할 필요 없이 Promise.all을 이용해주면 간편

async function get3Pokemon() {
	const prom1 = axios.get('http://pokeapi.co/api/v2/pokemon/1');
	const prom2 = axios.get('http://pokeapi.co/api/v2/pokemon/2');
	const prom3 = axios.get('http://pokeapi.co/api/v2/pokemon/3');
	console.log(prom1); // <pending>
	const results = await Promise.all([prom1, prom2, prom3]);
	console.log(prom1); // <resolved>

	printPokemon(results);
}
//this code will be runned after all the promises are resolved

function printPokemon(results) {
	for (let pokemon of results) {
		console.log(podata.name);
	}
}

get3Pokemon();

-모든 코드는 Promise들이 처리된 후에 실행된다.

'javascript' 카테고리의 다른 글

JavaScript/ The Async & The Await  (0) 2020.04.15
JavaScript/ AXIOS  (0) 2020.04.14
JavaScript/ Fetch API  (0) 2020.04.14
JavaScript/ AJAX & XML Http Request  (0) 2020.04.14
JavaScript/ CallBack Hell & Promise!  (0) 2020.04.14

 

<the ASYNC keyword>

: async function 선언은 이벤트 루프를 통해 비동기적으로 작동하는 함수로, 암시적으로 Promise를 사용하여 결과를 반환한다.

 

// REGULAR function returns a string:
function greet() {
return 'HELLO!!!';
}

// THE ASYNC KEYWORD!
// This function returns a promise.
async function greet() {
	return 'HELLO!!!'; //->resolved with the value of 'HELLO!!!'
}

greet().then((val) => {
	console.log('PROMISE RESOLVED WITH: ', val);
});
PROMISE RESOLVED WITH: HEllO!!!

 

 

- async function의 에러처리

// Equivalent non-async function...
// function add(x, y) {
// 	return new Promise((resolve, reject) => {
// 		if (typeof x !== 'number' || typeof y !== 'number') {
// 			reject('X and Y must be numbers!');
// 		}
// 		resolve(x + y);
// 	});
// }


async function add(x, y) {
	if (typeof x !== 'number' || typeof y !== 'number') {
		throw 'X and Y must be numbers!';
	}
	return x + y;
}


add(6, 7)
	.then((val) => {
		console.log('PROMISE RESOLVED WITH: ', val);
	})
	.catch((err) => {
		console.log('PROMISE REJECTED WITH: ', err);
	});

-> 예상된 에러 하나만 처리 가능

 

 

// ver 1
async function getPlanets() {
	//Invalid URL...
	const res = await axios.get('https://swapi.co/api/planeklsajdalksts/');
	console.log(res.data);
}

getPlanets().catch((err) => {
	console.log('IN CATCH!!!');
	console.log(err);
});

// ver 2
async function getPlanets() {
	try {
		const res = await axios.get('https://swapi.co/api/planeklsajdalksts/');
		console.log(res.data);
	} catch (e) {
		console.log('IN CATCH!', e);
	}
}
getPlanets();

-> 코드실행시 발생하는 모든 예외를 처리 가능

 

 

 

 

<the AWAIT keyword>

: async 함수에는 await식이 포함.

async 함수의 실행을 일시 중지하고 전달 된 Promise의 해결을 기다린 후, async 함수의 실행을 다시 시작하고 완료후 값을 반환.

 

async function getPlanets() {
	const res = await axios.get('https://swapi.co/api/planets/');
	console.log(res.data); //only runs once the previous line is complete (the axios promise is resolved)
}

getPlanets();



// Without async/await...

// function getPlanets() {
// 	return axios.get('https://swapi.co/api/planets/');
// }

// getPlanets().then((res) => {
// 	console.log(res.data);
// });

'javascript' 카테고리의 다른 글

JavaScript/ Parallel vs Sequential & Promise.all  (0) 2020.04.15
JavaScript/ AXIOS  (0) 2020.04.14
JavaScript/ Fetch API  (0) 2020.04.14
JavaScript/ AJAX & XML Http Request  (0) 2020.04.14
JavaScript/ CallBack Hell & Promise!  (0) 2020.04.14

<AXIOS> 

- Promise based HTTP client for the browser and node.js

- Features

  • Make XMLHttpRequests from the browser
  • Make http requests from node.js
  • Supports the Promise API
  • Intercept request and response
  • Transform request and response data
  • Cancel requests
  • Automatic transforms for JSON data
  • Client side support for protecting against XSRF

https://github.com/axios/axios

 

 

-> We don't have to do JSON parsing!
-> 'Catch Error' is worked!

-> Need to add Axios script in Html

 

 

axios
    .get('http://swapi.co/api/planets/')
    .then((res) => {
        console.log(res.data);
    })
    .catch((err) => {
        console.log(err);
    });

 

 

 

- Chained Request

axios
    .get('http://swapi.co/api/planets/')
    .then(({ data }) => {
        console.log(data);
        for (let planet of data.results) {
            console.log(planet.name);
        }
        return axios.get(data.next);
    })
    .then(({ data }) => {
        console.log(data);
        for (let planet of data.results) {
            console.log(planet.name);
        }
    })
    .catch((err) => {
        console.log('ERROR!!!', err);
    });

 

 

 

- Refactoring

const fetchNextPlanets = (url = 'http://swapi.co/api/planets/') => {
    return axios.get(url);
};

printPlanets = ({ data }) => {
    console.log(data);
    for (let planet of data.results) {
        console.log(planet.name);
    }
    return Promise.resolve(data.next);
};

fetchNextPlanets()
    .then(printPlanets)
    .then(fetchNextPlanets)
    .then(printPlanets)
    .then(fetchNextPlanets)
    .then(printPlanets)
    .catch((err) => {
        console.log('ERROR!!!', err);
    });

'javascript' 카테고리의 다른 글

JavaScript/ Parallel vs Sequential & Promise.all  (0) 2020.04.15
JavaScript/ The Async & The Await  (0) 2020.04.15
JavaScript/ Fetch API  (0) 2020.04.14
JavaScript/ AJAX & XML Http Request  (0) 2020.04.14
JavaScript/ CallBack Hell & Promise!  (0) 2020.04.14

 

 

<FETCH API>

- a newer way of making request wia JS

- supports promise

 

fetch('https://swapi.co/api/planets/')//promise
    .then((response) => {//get promise, need then
        if (!response.ok) { //2. so we need to check response here
            console.log('Somthing Wrong!');
            console.log(response.status);
        }
        return response.json(); //아래의 데이터로 리턴
    })
    .then((data) => {//get another promise, need another then
        console.log('Fetched all Planets');
        const filmURL = data.results[0].films[0];//첫플레닛 배열의 첫 필름 배열
        return fetch(filmURL)//promise  
    })
    .then((response) => {
        if (!response.ok) {
            console.log('Somthing Wrong!');
            console.log(response.status);
        }
        return response.json(); //아래의 데이터로 리턴
    })
    .then(data => {
        console.log('Fetched First Film, based on first planet');
        console.log(data.title);//첫필름배열의 타이틀 출력
    })
    .catch((err) => { // 1. if we put wrong address, this catch is not gonna runned(becoz we still get a response from API), unless sever is completley rejected the request(ex;200, internet shutdown or not ok).
        //->it is how fetch runned
        console.log('Somthing Wrong!');
        console.log(err);
    });

 

 

 

 

- Refactoring

const checkStatusAndParse = (response) => {
    if (!response.ok) {
        console.log('Somthing Wrong!');
        console.log(response.status);
    }
    return response.json();
};


const printPlanets = (data) => {
    console.log('Loaded 10 Planets');
    for (let planet of data.results) {
        console.log(planet.name);
    }
    return Promise.resolve(data.next);
};


const fetchNextPlanets = (url = 'https://swapi.co/api/planets/') => {
    return fetch(url);
};


fetchNextPlanets()//원하는 만큼 복사가능
    .then(checkStatusAndParse)
    .then(printPlanets)
    .then(fetchNextPlanets)
    .then(checkStatusAndParse)
    .then(printPlanets)
    .then(fetchNextPlanets)
    .then(checkStatusAndParse)
    .then(printPlanets)
    .catch((err) => {
        console.log('Somthing Wrong!');
        console.log(err);
    });

'javascript' 카테고리의 다른 글

JavaScript/ The Async & The Await  (0) 2020.04.15
JavaScript/ AXIOS  (0) 2020.04.14
JavaScript/ AJAX & XML Http Request  (0) 2020.04.14
JavaScript/ CallBack Hell & Promise!  (0) 2020.04.14
JavaScript/ Extends, Super and SubClasses!  (0) 2020.04.14

<AJAX>

- Asynchronous

- JavaScript

- And

- XML  -> not anymore, JSON replayed XML these days.

 

 

 

<XML Request>

- the OG way to send requests via JS

- does not support  the 'promise' -> need many callbacks!

- clunky syntax -> hard to remember  

const firstReq = new XMLHttpRequest();
firstReq.addEventListener('load', function () {
    console.log('First Req!!');
    const data = JSON.parse(this.responseText);

    const filmURL = data.results[0].films[0];
    const filmReq = new XMLHttpRequest();
    filmReq.addEventListener('load', function () {
        console.log('Second Req!!');
        const filmData = JSON.parse(this.responseText);
        console.log(filmData);
    });

    filmReq.addEventListener('error', function (e) {
        console.log('Error!!', e);
    });

    filmReq.open('GET', filmURL);
    filmReq.send();

    // for (let planet of data.results) {
    //     console.log(planet.name);
    // }
});

firstReq.addEventListener('error', () => {
    console.log('Error!!');

});

firstReq.open('GET', 'https://swapi.co/api/planets/');
firstReq.send();
console.log('req sented!')

'javascript' 카테고리의 다른 글

JavaScript/ AXIOS  (0) 2020.04.14
JavaScript/ Fetch API  (0) 2020.04.14
JavaScript/ CallBack Hell & Promise!  (0) 2020.04.14
JavaScript/ Extends, Super and SubClasses!  (0) 2020.04.14
JavaScript/ 프로토타입과 클래스, THE NEW OPERATOR!!  (0) 2020.04.14

JavaScript is single thread language.

then, How asynchronous callback work?

-> the browser does work. 

: Browsers came with Wep APIs that are abled to handle certain tasks in the background. (like 'request' or 'setTimeout')

 

: JavaScript recognize this and pass the tasks to the browser!

 

 

 

 

<ex of callback hell : why we need the 'PROMISE'>

const btn = document.querySelector('button');

//This function moves an element "amount" number of pixels after a delay.
//If the element will stay on screen, we move the element and call the onSuccess callback function
//If the element will move off screen, we do not move the element and instead call the onFailure callback
const moveX = (element, amount, delay, onSuccess, onFailure) => {
	setTimeout(() => {
		const bodyBoundary = document.body.clientWidth;
		const elRight = element.getBoundingClientRect().right;
		const currLeft = element.getBoundingClientRect().left;
		if (elRight + amount > bodyBoundary) {
			onFailure();
		}
		else {
			element.style.transform = `translateX(${currLeft + amount}px)`;
			onSuccess();
		}
	}, delay);
};

// LOOK AT THIS UGLY MESS!
moveX(
	btn,
	300,
	1000,
	() => {
		//success callback
		moveX(
			btn,
			300,
			1000,
			() => {
				//success callback
				moveX(
					btn,
					300,
					1000,
					() => {
						//success callback
						moveX(
							btn,
							300,
							1000,
							() => {
								//success callback
								moveX(
									btn,
									300,
									1000,
									() => {
										//success callback
										alert('YOU HAVE A WIDE SCREEN!');
									},
									() => {
										//failure callback
										alert('CANNOT MOVE FURTHER!');
									}
								);
							},
							() => {
								//failure callback
								alert('CANNOT MOVE FURTHER!');
							}
						);
					},
					() => {
						//failure callback
						alert('CANNOT MOVE FURTHER!');
					}
				);
			},
			() => {
				//failure callback
				alert('CANNOT MOVE FURTHER!');
			}
		);
	},
	() => {
		//failure callback
		alert('CANNOT MOVE FURTHER!');
	}
);

 

 

 

 

<Promise>

: Promise is an object representing the eventual completion or failure of an asynchronous operation.

 

const willGetYouADog = new Promise((resolve, reject) => {
	const rand = Math.random();
	if (rand < 0.5) {
		resolve();
	}
	else {
		reject();
	}
});
willGetYouADog.then(() => {
	console.log('YAY WE GOT A DOG!!!!');
});
willGetYouADog.catch(() => {
	console.log(':( NO DOG');
});
const makeDogPromise = () => {
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			const rand = Math.random();
			if (rand < 0.5) {
				resolve();
			}
			else {
				reject();
			}
		}, 5000);
	});
};
makeDogPromise()
	.then(() => { //if it resolved
		console.log('YAY WE GOT A DOG!!!!');
	})
	.catch(() => { //if it rejected
		console.log(':( NO DOG');
	});

 

it is on pending, until the code is resolved or rejected.

you can check status of the promise in console. { <Pending>, <Resolved>, <Rejected> }

 

 

 

 

 

 

<Refactoring CallBack Hell with the Promise>

const moveX = (element, amount, delay) => {
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			const bodyBoundary = document.body.clientWidth;
			const elRight = element.getBoundingClientRect().right;
			const currLeft = element.getBoundingClientRect().left;
			if (elRight + amount > bodyBoundary) {
				reject({ bodyBoundary, elRight, amount });
			}
			else {
				element.style.transform = `translateX(${currLeft + amount}px)`;
				resolve();
			}
		}, delay);
	});
};

const btn = document.querySelector('button');
moveX(btn, 100, 1000)
	.then(() => moveX(btn, 100, 1000))
	.then(() => moveX(btn, 100, 1000))
	.then(() => moveX(btn, 100, 1000))
	.then(() => moveX(btn, 100, 1000))
	.then(() => moveX(btn, 100, 1000))
	.then(() => moveX(btn, 100, 1000))
	.then(() => moveX(btn, 100, 1000))
	.then(() => moveX(btn, 100, 1000))
	.then(() => moveX(btn, 100, 1000))
	.then(() => moveX(btn, 100, 1000))
	.then(() => moveX(btn, 100, 1000))
	.then(() => moveX(btn, 100, 1000))
	.then(() => moveX(btn, 100, 1000))
	.then(() => moveX(btn, 100, 1000))
	.then(() => moveX(btn, 100, 1000))
	.catch(({ bodyBoundary, amount, elRight }) => {
		console.log(`Cannot Move! Body is ${bodyBoundary}px wide`);
		console.log(`Element is at ${elRight}px, ${amount}px is too large!`);
	});

 

class Pet {
	constructor (name, age) {
		this.name = name;
		this.age = age;
	}
	eat () {
		return `${this.name} is eating!`;
	}
}

class Cat extends Pet {
	//super is referenced super class(which is Pet class in this case)
	constructor (name, age, livesleft = 9) {
		super(name, age);
		this.livesleft = livesleft;
	}

	//pet의 생성자를 빌려와서 새로운 Cat객체를 생성가능
	meow () {
		return 'MEOWWWW!!';
	}
}

const nabi = new Cat('Nabi', 2);

class Dog extends Pet {
	//pet의 생성자를 빌려와서 새로운 Dog객체를 생성가능
	bark () {
		return 'WOOOF!!!';
	}
	eat () {
		return `${this.name} scarfs his foods!`;
	} //Pet class의 eat메소드를 over write
}

const rug = new Dog('Rug', 7);

<프로토타입>

:The __proto__ getter function exposes the value of the internal [[Prototype]] of an object. For objects created using an object literal, this value is Object.prototype. For objects created using array literals, this value is Array.prototype. For functions, this value is Function.prototype. For objects created using new fun, where fun is one of the built-in constructor functions provided by JavaScript (Array, Boolean, Date, Number, Object, String, and so on — including new constructors added as JavaScript evolves), this value is always fun.prototype. For objects created using new fun, where fun is a function defined in a script, this value is the value of fun.prototype. (That is, if the constructor didn't return an other object explicitly, or the fun.prototype has been reassigned since the instance was created).

//String.prototype is a "template object" for every single string.
//We could go crazy and add our own method called yell...
String.prototype.yell = function() {
	return `OMG!!! ${this.toUpperCase()}!!!!! AGHGHGHG!`;
};

'bees'.yell(); //"OMG!!! BEES!!!!! AGHGHGHG!"

//We can overwrite an existing Array method like pop (not a good idea):
Array.prototype.pop = function() {
	return 'SORRY I WANT THAT ELEMENT, I WILL NEVER POP IT OFF!';
};
const nums = [ 6, 7, 8, 9 ];
nums.pop(); // "SORRY I WANT THAT ELEMENT, I WILL NEVER POP IT OFF!"

 

 

 

<Factory Function 옳지 않은 예시>

function hex (r, g, b) {
	return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}

function rgb (r, g, b) {
	return `rgb(${r},${g},${b})`;
}

hex(255, 100, 25);
rgb(255, 100, 25);

function makeColor (r, g, b) {
	//펑션안에 메소드를 추가해서 어디서나 접근가능
	const color = {};
	color.r = r;
	color.g = g;
	color.b = b;
	color.rgb = function () {
		const { r, g, b } = this;
		//return `rgb(${r},${g},${b})`;
	};
	color.hex = function () {
		const { r, g, b } = this;
		return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16) + slice(1);
	};
	return color;
}

const firstColor = makeColor(35, 40, 190);
firstColor.hex();
firstColor.rgb();

const black = makeColor(0, 0, 0);
black.hex();
black.rgb();

 

firstColor.hex !== black.hex

: 프로토타입에 저장된 메소드들과는 달리 두메소드는 각자의 firstColor와 black객체를 참조하기 떄문에 참조값이 다름

 

'hello'.slice === 'hi'.slice

: slice가 String.prototype.slice를 참조하기 때문

 

 

 

 

 

<THE NEW OPERATOR!>

function Color (r, g, b) {
	this.r = r;
	this.g = g;
	this.b = b;
	//console.log(this); // window obj를 프린트
}

//프로토타입을 이용해 프로토타입안에 메소드를 정의
Color.prototype.rgb = function () {
	const { r, g, b } = this;
	return `rgb(${r},${g},${b})`;
};

Color.prototype.hex = function () {
	const { r, g, b } = this;
	return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16) + slice(1);
};

Color.prototype.rgba = function (a = 1.0) {
	const { r, g, b } = this;
	return `rgba(${r},${g},${b},${a})`;
};

//-> We develope recipe for Color

const color1 = new Color(255, 40, 100);
const color2 = new Color(0, 0, 0);
//new를 붙혀새로운 obj를 생성

color1.rgba(0.4);

 

-> 콘솔을 통해 color1, 2을 확인하면 color1, 2의 _proto_안에 rgb, hex 메소드가 정의된 것을 확인 할 수 있음

 

color1.rgb === color2.rgb

color1.hex === color2.hex

: Colol.prototype에 정의된 메소드를 참조하기 때문

 

 

 

 

 

<THE CLASS!>

클래스를 이용해 위의 코드를 재구성

class Color {
	// constructor is function that excuted immediately whenever new color is created.
	constructor (r, g, b, name) {
		this.r = r;
		this.g = g;
		this.b = b;
		this.name = name;
	}
	innerRGB () {
		const { r, g, b } = this;
		return `${r},${g},${b}`;
	}
	rgb () {
		return `rgb(${this.innerRGB()})`;
	}
	rgba (a = 1.0) {
		return `rgba(${this.innerRGB()}, ${a})`;
	}
	hex () {
		return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16) + slice(1);
	}
}

//Color.prototype.rgb
//Color.prototype.rgba
//Color.prototype.hex

const color1 = new Color(255, 45, 78, 'tomato');
const color2 = new Color(255, 255, 255, 'white');

//color1.hex === color2.hex //true

color1.rgba(0.5);

 

 

 

 

<MORE CLASS!!>

class Color {
	constructor(r, g, b, name) {
		this.r = r;
		this.g = g;
		this.b = b;
		this.name = name;
		this.calcHSL();
	}
	innerRGB() {
		const { r, g, b } = this;
		return `${r}, ${g}, ${b}`;
	}
	rgb() {
		return `rgb(${this.innerRGB()})`;
	}
	rgba(a = 1.0) {
		return `rgba(${this.innerRGB()}, ${a})`;
	}
	hex() {
		const { r, g, b } = this;
		return (
			'#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)
		);
	}
	hsl() {
		const { h, s, l } = this;
		return `hsl(${h},${s}%, ${l}%)`;
	}
	fulllySaturated() {
		const { h, l } = this;
		return `hsl(${h},100%, ${l}%)`;
	}
	opposite() {
		const { h, s, l } = this;
		const newHue = (h + 180) % 360;
		return `hsl(${newHue},${s}%, ${l}%)`;
	}
	calcHSL() {
		let { r, g, b } = this;
		// Make r, g, and b fractions of 1
		r /= 255;
		g /= 255;
		b /= 255;

		// Find greatest and smallest channel values
		let cmin = Math.min(r, g, b),
			cmax = Math.max(r, g, b),
			delta = cmax - cmin,
			h = 0,
			s = 0,
			l = 0;
		if (delta == 0) h = 0;
		else if (cmax == r)
			// Red is max
			h = ((g - b) / delta) % 6;
		else if (cmax == g)
			// Green is max
			h = (b - r) / delta + 2;
		else
			// Blue is max
			h = (r - g) / delta + 4;

		h = Math.round(h * 60);

		// Make negative hues positive behind 360°
		if (h < 0) h += 360;
		// Calculate lightness
		l = (cmax + cmin) / 2;

		// Calculate saturation
		s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));

		// Multiply l and s by 100
		s = +(s * 100).toFixed(1);
		l = +(l * 100).toFixed(1);
		this.h = h;
		this.s = s;
		this.l = l;
	}
}
const red = new Color(255, 67, 89, 'tomato');
red.hsl();
red.opposite();
red.rgba(0.3);
const white = new Color(255, 255, 255, 'white');

 

 

 

 

 

'javascript' 카테고리의 다른 글

JavaScript/ CallBack Hell & Promise!  (0) 2020.04.14
JavaScript/ Extends, Super and SubClasses!  (0) 2020.04.14
JavaScript/ Functions!! 함수들  (0) 2020.04.14
JavaScript/ ES5 vs ES6  (0) 2020.03.09
JavaScript/ let , const & var  (0) 2020.03.09