javascript
JavaScript/ CallBack Hell & Promise!
MyaZ
2020. 4. 14. 10:40
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!`);
});