0% found this document useful (0 votes)
3 views39 pages

CH13 Promise

The document discusses the concept of Promises in JavaScript, highlighting the differences between synchronous and asynchronous programming. It explains how Promises allow for better handling of asynchronous operations, enabling chaining and improved error management compared to traditional callback methods. The document also includes examples of using Promises with HTTP requests and demonstrates the structure and states of a Promise.

Uploaded by

koominjae9
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views39 pages

CH13 Promise

The document discusses the concept of Promises in JavaScript, highlighting the differences between synchronous and asynchronous programming. It explains how Promises allow for better handling of asynchronous operations, enabling chaining and improved error management compared to traditional callback methods. The document also includes examples of using Promises with HTTP requests and demonstrates the structure and states of a Promise.

Uploaded by

koominjae9
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 39

CAS 2109-01 Internet Programming

Spring 2025

Promise

Yonsei University

“본 강의자료는 연세대학교 학생들을 위해 수업목적으로 제작ㆍ게시된 것이므로


수업목적 외 용도로 사용할 수 없으며, 다른 사람들과 공유할 수 없습니다. 위반에
따른 법적 책임은 행위자 본인에게 있습니다.”
Promise CAS2109-01

• Synchronous
• Only one operation can be in progress at a time

• Asynchronous
• Allow a program to do more than one thing at a time
• Effectively handle potential blocking operations such as fetching a
resource from a server (TaskA) and applying a filter to it (TaskB)

TaskA (w async operation)

can potentially
take a long time

TaskB

https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous
2
Promise CAS2109-01

• Here is a very inefficient algorithm of generating multiple large prime


numbers when a user clicks the "Generate primes" button
• The higher the number of primes a user specifies, the longer the
operation will take.

<label for="quota">Number of primes:</label>


<input type="text" id="quota" name="quota" value="1000000" />
<button id="generate">Generate primes</button>
<button id="reload">Reload</button>
<div id="output"></div>

https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Introducing
3
Promise CAS2109-01

const MAX_PRIME = 1000000;


function isPrime(n) {
for (let i = 2; i <= Math.sqrt(n); i++) {
if (n % i === 0) { return false; }
}
return n > 1;
}
const random = (max) => Math.floor(Math.random() * max);
function generatePrimes(quota) {
const primes = [];
while (primes.length < quota) {
const candidate = random(MAX_PRIME);
if (isPrime(candidate)) { primes.push(candidate); }
}
return primes;
}
const quota = document.querySelector('#quota');
const output = document.querySelector('#output');
document.querySelector('#generate').addEventListener('click', () => {
const primes = generatePrimes(quota.value);
output.textContent = `Finished generating ${quota.value} primes!`;
});
document.querySelector('#reload').addEventListener('click', () => {
document.location.reload();
});
4
Promise CAS2109-01

• What if the synchronous function takes a long time?


• Takes a few seconds before displaying the "Finished!" message

• If we add a text box for you to type in. This time, click "Generate
primes", and try typing in the text box immediately after
• The program is completely unresponsive: can't type anything

5
Promise CAS2109-01

• Two main types of asynchronous code style

• (old-style) async callbacks vs. (newer) promise-style code

• Callbacks were the main way of implementing asynchronous


functions

• Most modern asynchronous APIs are Promise1-based

1 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

6
Promise CAS2109-01

• Async callbacks are specified as arguments when calling a function

• When passing a callback as an argument to another function

• The callback function is not executed immediately


• Is “called back” (hence the name) asynchronously somewhere
inside the containing function’s body

• The containing function is responsible for executing the callback


function when the time comes

//delaying the execution of a timer function

setTimeout(callback, 2000);

https://www.w3schools.com/jsref/met_win_settimeout.asp
7
Promise CAS2109-01

• Steps that you have to take for your order to be successful


• Request menu
• Choose toppings
• Order pizza
• Check pizza
• Eat pizza
• Pay for pizza
• Each step cannot continue before the previous finishes
• This is a common situation if we need to perform some operation
that breaks down into a series of asynchronous functions
• We can keep playing video games while waiting for the pizza

8
Promise CAS2109-01

• With callbacks: hard to read and debug


function order() {
setTimeout(function() {
requestMenu("Requesting menu...");
setTimeout(function() {
chooseTopping(“Choosing toppings...");
setTimeout(function() {
placeOrder("Ordering pizza...");
setTimeout(function() {
checkPizza("Checking pizza...");
setTimeout(function() {
eatPizza("Eating pizza...");
setTimeout(function() {
payForPizza("Paying for pizza...");
setTimeout(function() {console.log(response); }, ?);
}, ?); }, ?); }, ?); }, ?); }, ?); }, ?); }
• Often ends up with a messy "pyramid of doom" (aka, callback hell)
• Callback-based code can get hard to understand
9
Promise CAS2109-01

• What if we could make our code be felt more synchronous?


(코드가 더 동기적으로 느껴지도록 만들 수 있다면 어떨까요?)
orderPizza()
.then(placeOrder)
.then(eatPizza)
.then(payForPizza)
.catch(badPizza);

• Allow us to chain multiple async operations together


• Allow us to handle all errors in one place
• Only once at the top level

10
Promise CAS2109-01

• Allows browser to make HTTP requests to server


• Simpler and more efficient version of XMLHttpRequest
• Returns a Promise object immediately
• Uses the then() and catch() methods
• 예제: The Can Store 2
fetch('products.json')
.then(function(response) {
return response.json(); }) //return JSON data
.then(function(json) {
let products = json;
initialize(products); })
.catch(function(err) {
console.log('Fetch problem: ' + err.message); });
1 https://developer.mozilla.org/en-US/docs/Web/API/Window/fetch
2 https://github.com/mdn/learning-area/blob/master/javascript/apis/fetching-data/can-store/can-script.js
11
Promise CAS2109-01

[ {
{ "name" : "mushy peas",
"name" : "baked beans", "price" : 0.58,
"price" : 0.40, "image" : "mushypeas.jpg",
"image" : "beans.jpg", "type" : "vegetables"
"type" : "vegetables" },
}, {
{ "name" : "corned beef",
"name" : "hot dogs", "price" : 2.39,
"price" : 1.99, "image" : "cornedbeef.jpg",
"image" : "hotdogs.jpg", "type" : "meat"
"type" : "meat" },
}, {
{ "name" : "tomato soup",
"name" : "spam", "price" : 1.40,
"price" : 2.85, "image" : "tomatosoup.jpg",
"image" : "spam.jpg", "type" : "soup"
"type" : "meat" },
}, products.json {
{ "name" : "chopped tomatoes",
"name" : "refried beans", "price" : 0.45,
"price" : 0.99, "image" : "tomato.jpg",
"image" : "refried.jpg", "type" : "vegetables"
"type" : "vegetables" },
}, {
{ "name" : "chicken noodle soup",
"name" : "kidney beans", "price" : 1.89,
"price" : 0.58, "image" : "chickennoodle.jpg",
"image" : "kidney.jpg", "type" : "soup"
"type" : "vegetables" },
}, {
{ "name" : "carrot and coriander soup",
"name" : "garden peas", "price" : 1.49,
"price" : 0.52, "image" : "carrotcoriander.jpg",
"image" : "gardenpeas.jpg", "type" : "soup"
"type" : "vegetables" }
}, ]
https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json 12
Promise CAS2109-01

Example: The Can Store

동영상

https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/ 13
Promise CAS2109-01

console.log ('Starting');
let image;
fetch('coffee.jpg').then((response) => {
console.log('It worked :)')
return response.blob(); // Binary Large Object (이미지, 사운드, 비디오)
}).then((myBlob) => {
let objectURL = URL.createObjectURL(myBlob); // URL 생성
image = document.createElement('img');
image.src = objectURL;
document.body.appendChild(image);
}).catch((error) => {
console.log('There has been a problem with your fetch operation: ' +
error.message);
});
console.log ('All done!');

14
Promise CAS2109-01

console.log ('Starting');
let image;
fetch('coffee.jpg').then((response) => {
console.log('It worked :)')
return response.blob(); //returns a Promise object1
}).then((myBlob) => {
let objectURL = URL.createObjectURL(myBlob);
image = document.createElement('img');
image.src = objectURL;
document.body.appendChild(image);
}).catch((error) => {
console.log('There has been a problem with your fetch operation: ' +
error.message);
});
console.log ('All done! ' + image.src + ' displayed.');
TypeError: image is undefined; can't access its "src" property
1 https://developer.mozilla.org/en-US/docs/Web/API/Response/blob 15
Promise CAS2109-01

• Let’s make the three console.log() statements appear in the desired order
console.log ('Starting');
let image;
fetch('coffee.jpg').then((response) => {
console.log('It worked :)')
return response.blob();
}).then((myBlob) => {
let objectURL = URL.createObjectURL(myBlob);
image = document.createElement('img');
image.src = objectURL;
document.body.appendChild(image);
}).then(() => {
console.log ('All done! ' + image.src + ' displayed.');
}).catch((err) => {
console.log('There has been a problem with your fetch operation: ' + err.message);
});
16
JavaScript CSI-2109-01

• The foundation of modern asynchronous programming


• An object returned by an asynchronous function
• Represents the eventual2 completion or failure of an async operation
• “I promise to get back to you with the answer as soon as I can”
• Uncertainty in when it happens
• How long that will take or if it even will come back correctly
• At the time the promise is returned to the caller, the operation often
isn't finished
• But the promise object provides methods to handle the eventual
success or failure of the operation

1 https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Promises
2 “coming or happening at a later time” 17
Promise CAS2109-01

• We can attach callback functions (handlers) to the promise object

• We attach callback functions (handler functions) to the promise


object returned

• The handlers will be executed when the promise operation has


succeeded or failed

18
Promise CAS2109-01

• then() block (method)1

• Contains a handler that will run when the fetch operation succeeds
• The promise will call the handler, passing in a Response object2, which
contains the server's response

• The handler receives as input the result of the operation

• Returns another promise immediately


• Mean that we can chain multiple .then() blocks onto each other

• So multiple asynchronous operations can run in order

1 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
2 https://developer.mozilla.org/en-US/docs/Web/API/Response

19
Promise CAS2109-01

• A promise can be in one of three states:

• pending: the promise has been created, and the asynchronous


function has not succeeded or failed yet
• The "pending" state means that the fetch operation is still going on

• fulfilled: the asynchronous function has succeeded. When a


promise is fulfilled, its then() handler is called

• rejected: the asynchronous function has failed. When a promise is


rejected, its catch() handler is called.

https://www.w3schools.com/js/js_promise.asp
20
Promise CAS2109-01

동영상1

1 동영상 녹화 시점 (환율 조회 기준일) 은 2023년 5월임


21
Promise CAS2109-01

// 템플릿 리터럴. 따옴표 대신에 백틱을 사용

22
Promise CAS2109-01

• Communicate with an API and get back the data asynchronously

http://api.exchangeratesapi.io/
23
Promise CAS2109-01

• When reaching the bottom of a page, load an additional set of posts


or articles repeatedly as follows:

• Detect when we've reached the end of the page

• Using window.onscroll (from CH10-JS Events)

• Load the additional content asynchronously

• Modify the DOM to add the content to the existing page

24
Promise CAS2109-01

25
Promise CAS2109-01

26
Promise CAS2109-01

27
Promise 동영상 CAS2109-01

28
Promise CAS2109-01

• Can chain multiple async operations together using multiple then(),


passing the result of one into the next one as an input

• This is much harder to do with callbacks

• Error handling is much better

• All errors are handled by a single catch() block

29
Promise CAS2109-01

• Forming a promise chain


• Easier to see what is going on
• Each operation is guaranteed to wait for previous operations to
complete before running
• Only need a single catch() block to handle all the errors
• Doesn't block the main thread
• So we can keep playing video games while waiting for the pizza

chooseToppings() chooseToppings()
.then(function(toppings) { .then(toppings =>
return placeOrder(toppings); placeOrder(toppings)
}) )
.then(function(order) { .then(order =>
return collectOrder(order); collectOrder(order)
}) )
.then(function(pizza) { .then(pizza =>
eatPizza(pizza); eatPizza(pizza)
}) )
.catch(failureCallback); .catch(failureCallback);
30
Promise CAS2109-01

• finally() method
• Run a final block of code after a promise completes
• Regardless of whether it fulfilled or rejected
myPromise myPromise
.then(response => {
.then(response => {
doSomething(response);
doSomething(response); })
runFinalCode(); .catch(e => {
}) returnError(e);
})
.catch(e => {
.finally(() => {
returnError(e);
runFinalCode();
runFinalCode(); });
});

31
Promise CAS2109-01

• Promises are similar to event listeners, but with a few differences:

• A promise can only succeed or fail once


• It cannot succeed or fail twice

• If a promise has succeeded or failed and you later add a


success/failure handler
• The correct handler will be called even if the promise was resolved
earlier

32
Promise CAS2109-01

• What if you want to run some code only after a whole bunch of
promises have all fulfilled?

• Promise.all() method takes an array of promises and returns a single


promise

Promise.all([a, b, c]).then(values => {


...
});
• If they all (all promises in the array) fulfil, the then() handler is called
with an array of all the responses
• If any of the promises passed to Promise.all() is rejected
• The whole block will reject

• If you need any one of a set of promises to be fulfilled: Promise.any()

33
Promise CAS2109-01

• Use the async/await syntactic sugar


• Makes our code look synchronous (more readable)
async function foo() { // turn it into an async function
try {
const result = await doSomething();
const newResult = await doSomethingElse(result);
const finalResult = await doThirdThing(newResult);
console.log(`Got the final result: ${finalResult}`);
} catch(error) { failureCallback(error); }
}
• Can just have regular functions rather than callbacks
• For error-handling, must use try/catch instead of .then/.catch

https://developers.google.com/web/fundamentals/primers/async-functions
34
Promise CAS2109-01

• The following function returns "Hello"


function hello() { return "Hello" };
hello();

• What if we turn this into an async function?


async function hello() { return "Hello" };
hello(); // returns a promise

• async tells functions to return a promise


• Rather than directly returning the value

• To actually consume the value returned when the promise fulfills, use then()

hello().then((value) => console.log(value));

https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Promises#async_and_await
35
Promise CAS2109-01

• Inside an async function, we can use the await keyword before a


call to a function that returns a promise

• await can be put in front of any async promise-based function to


pause your code on that line until the promise is settled

• The fulfilled value of the promise is returned, or

• The rejected value is thrown

36
Promise CAS2109-01

fetch('coffee.jpg')
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
return response.blob();
})
.then(myBlob => {
let objectURL = URL.createObjectURL(myBlob);
let image = document.createElement('img');
image.src = objectURL;
document.body.appendChild(image);
})
.catch(e => {
console.log('There has been a problem:' + e.message);
});
37
Promise CAS2109-01

• Call await fetch(), and instead of getting a promise, get back a


Response object, just as if fetch() were a synchronous function

async function myFetch() {


try {
let response = await fetch('coffee.jpg');
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
let myBlob = await response.blob(); // returns a promise
let objectURL = URL.createObjectURL(myBlob);
let image = document.createElement('img');
image.src = objectURL;
document.body.appendChild(image);
}
catch(error) { console.log(`There has been a problem:' + ${error}`); }
}
myFetch(); Makes code much simpler and easier to understand
38
JavaScript CSI-2109-01

• Slides are adapted from the following resource:


• Asynchronous JavaScript
• https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous

39

You might also like