#TIL (May 15th, 서른번째 이야기)

Jung Hyun Kim·2020년 5월 15일
0

Javascript callback/promises

Asynchronous Callbacks(비동기처리와 콜백함수)

promise

-A pattern for writing codes
-JS object, promising or guranteeing of an eventual value that takes some time

const willGetyouADog = new Promise((resolve, reject) => {
  const rand = Math.random();
  if(rand < 0.5) {
    resolve();
  } else {
    reject();
  }})
  ;

willGetYouADog.then() => { // then은 resolved 되었을때 동시에 실행되는 코드이다 
  
  console.log('yay we got a dog !!');
}

willGetYouADog.catch(() => {
  console.log("no dog");}
                     );

만약 여기에 타이머를 설정한다면??

const willGetyouADog = new Promise((resolve, reject) => {
  setTimeout(() => {
  const rand = Math.random();
  if(rand < 0.5) {
    resolve();
  } else {
    reject();
  }
  }, 5000);
});

willGetYouADog.then() => { 
  console.log('yay we got a dog !!');
}
willGetYouADog.catch(() => {
  console.log("no dog");}
                     );

이것을 variable로 묶을 수도 있음

const makeDogPromise = () => {
  return new Promise((resolve, reject) => {
  setTimeout(() => {
  const rand = Math.random();
  if(rand < 0.5) {
    resolve();
  } else {
    reject();
  }
  }, 5000);
});

makeDogPromise() 
.then(() => { 
  console.log('yay we got a dog !!');
})
.catch(() => {
  console.log("no dog");
});

Resolving and rejecting with values

const fakeRequest = (url) => {
  return new Promise((resolve,reject) => {
    setTimeout(() => {
      const rand = Math.random();
      if (rand < 0.3) {
        reject({status: 404});
      }
      else { 
        const pages = {
        '/users': [
          {id:1, username : 'joanne'},
          {id:5, username : 'kiki'}
        ],
          '/about' : 'This is about page!'
        };
        const data = pages[url]
        resolve({status : 200, data});
      }
    },3000);
  });
};

fakeRequest('/users')
.then((res) => {
  console.log('Status code',res.status);
  console.log('Data', res.data);
  console.log('REQUEST WORKED!');
})
.catch((res)=> {
  console.log(res.status);
console.log('REQUEST FAILED')
});

만약 여기에서 없는 아래의 내용을 출력하면

fakeRequest('/dogs') 
//404 'REQUEST FAILED'가 출력된다 

Chaining multiple promises

  • resolve()가 호출되면 프로미스가 대기 상태에서 이행 상태로 넘어가기 때문에 첫 번째 .then()의 로직으로 넘어갑니다. 첫 번째 .then()에서는 이행된 결과 값 1을 받아서 10을 더한 후 그다음 .then() 으로 넘겨줍니다. 두 번째 .then()에서도 마찬가지로 바로 이전 프로미스의 결과 값 11을 받아서 20을 더하고 다음 .then()으로 넘겨줍니다. 마지막 .then()에서 최종 결과 값 31을 출력함.

  • promise 끝에는 catch()를 붙여서 에러를 처리하는것이 좋음

new Promise(function(resolve, reject){
  setTimeout(function() {
    resolve(1);
  }, 2000);
})
.then(function(result) {
  console.log(result); // 1
  return result + 10;
})
.then(function(result) {
  console.log(result); // 11
  return result + 20;
})
.then(function(result) {
  console.log(result); // 31
});

예시 출처 : https://joshua1988.github.io/web-development/javascript/promise-for-beginners/

  • 더 자세한 예시
const fakeRequest = (url) => {
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			const pages = {
				'/users'        : [
					{ id: 1, username: 'Bilbo' },
					{ id: 5, username: 'Esmerelda' }
				],
				'/users/1'      : {
					id        : 1,
					username  : 'Bilbo',
					upvotes   : 360,
					city      : 'Lisbon',
					topPostId : 454321
				},
				'/users/5'      : {
					id       : 5,
					username : 'Esmerelda',
					upvotes  : 571,
					city     : 'Honolulu'
				},
				'/posts/454321' : {
					id    : 454321,
					title :
						'Ladies & Gentlemen, may I introduce my pet pig, Hamlet'
				},
				'/about'        : 'This is the about page!'
			};
			const data = pages[url];
			if (data) {
				resolve({ status: 200, data }); //resolve with a value!
			}
			else {
				reject({ status: 404 }); //reject with a value!
			}
		}, 1000);
	});
};

fakeRequest('/users')
	.then((res) => {
		console.log(res);
		const id = res.data[0].id;
		return fakeRequest(`/users/${id}`);
	})
	.then((res) => {
		console.log(res);
		const postId = res.data.topPostId;
		return fakeRequest(`/posts/${postId}`);
	})
	.then((res) => {
		console.log(res);
	})
	.catch((err) => {
		console.log('OH NO!', err);
	});


프로미스의 처리 흐름 출처 MDN

Refactoring w/ Promises

  • 이전에 했었던 내용 중에 버튼 이동하는 부분을 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!`);
	});

JSON

JavaScript Object Notation
데이터를 보내기위해 사용됨, JS와 비슷하지만 Javascript는 아님

XML

profile
코린이 프론트엔드 개발자💻💛🤙🏼

0개의 댓글