Promises (JavaScript)

Ace your homework & exams now with Quizwiz!

The failure callback is sometimes called the

"failure handler function" or the onRejected function.

The success callback is sometimes called the

"success handler function" or the onFulfilled function

Since JavaScript doesn't mind whitespace, we follow a common convention of putting each part of this chain on a new line to make it easier to read. To create even more readable code, we can use a different promise function:

.catch()

Using .catch() accomplishes the same thing as using a

.then() with only a failure handler.

The executor function generally starts an...

asynchronous operation and dictates how the promise should be settled.

What does the promise look like?

const executorFunction = (resolve, reject) => { }; constmyFirstPromise = newPromise(executorFunction);

Example of a created promise:

const inventory = { sunglasses: 1900, pants: 1088, bags: 1344 }; // Write your code below: const myExecutor = (resolve,reject) =>{ if(inventory.sunglasses > 0){ resolve('Sunglasses order processed.') } else{ reject('That item is sold out.') } } const orderSunglasses = () =>{ return new Promise(myExecutor) } const orderPromise = orderSunglasses() console.log(orderPromise)

Example setTimeout()

const money = () => { return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve("NeoTheater") },1000) }) } const sadness = money(); console.log(sadness) //and function neotheater(){ console.log("Neotheater"); let eight = 8 if(eight == 8){ console.log(8) } } setTimeout(neotheater,1000)

Example of .then() linking

const p2 = new Promise((resolve, reject) => { resolve(2); }); p2.then((val)=>{ return new Promise((res,rej)=>{ if(val == 2){ res("Good") } else { rej("err") } }) }).then(console.log).catch(console.log);

Example of promise.all()

function cost(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ if(10 == 10){ resolve("Just right") } else{ reject("NO") } }) }) } function price(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ if(11 == 11){ resolve("Just right Yes") } else{ reject("NOOOOOO") } }) }) } const success = (e) =>{ console.log(e) } const failure = (f)=>{ console.log(f) } const hello = Promise.all([cost(),price()]) hello.then(success).catch(failure)

Another example of .then() linking

function generateNumber(num) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(num); }, 3 * 1000); }); } generateNumber(10) .then((result) => { console.log(result); return generateNumber(result * 2); }) .then((result) => { console.log(result); return generateNumber(result * 3); }) .then((result) => console.log(result)); (Another One)

Example of Success and Failure Callback Functions

function hello(solve){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ let reducing = 0; for(let i = 0; i < solve.length; i++){ reducing += solve[i] } if(reducing >= 10){ resolve("It bigger than 10 ," + reducing) } else{ reject("It's less than 10 ," + reducing) } },1000) }) } const handleSuccess = (success) =>{ console.log(success) } const handleFailure = (failure) =>{ console.log(failure) } hello([1,2]).then(handleSuccess,handleFailure)

What are callback functions also called?

handlers

Example of .then()

hello([1,2]).then(handleSuccess,handleFailure)

setTimeout()

is a Node API (a comparable API is provided by web browsers) that uses callback functions to schedule tasks to be performed after a delay.

If the appropriate handler is not provided, instead of throwing an error, .then() will do what?

just return a promise with the same settled value as the promise it was called on.

One common pattern we'll see with asynchronous programming is what?

multiple operations which depend on each other to execute or that must be executed in a certain order.

Remember, .then() will return a promise with the same settled value as the promise it was called on if what?

no appropriate handler was provided. This implementation allows us to separate our resolved logic from our rejected logic.

separation of concerns

organizing code into distinct sections each handling a specific task. It enables us to quickly navigate our code and know where to look if something isn't working.

Example of two .then() linked together

prom .then((resolvedValue) => { console.log(resolvedValue); }) .then(null, (rejectionReason) => { console.log(rejectionReason); });

Promises

Objects that represent the eventual outcome of an asynchronous operation

What is one important feature of .then()

One important feature of .then() is that it always returns a promise.

The Promise constructor method takes what?

A function parameter called the executor function which runs automatically when the constructor is called.

The resolve() and reject() functions aren't defined by the programmer. When the Promise constructor runs, what happens?

JavaScript will pass its own resolve() and reject() functions into the executor function.

There are countless examples of asynchronicity in our everyday lives.

Cleaning our house, for example, involves asynchronous operations such as a dishwasher washing our dishes or a washing machine washing our clothes. While we wait on the completion of those operations, we're free to do other chores.

prom .then((resolvedValue) => { console.log(resolvedValue); }) .catch((rejectionReason) => { console.log(rejectionReason); }); What does this code do?

Let's break down what's happening in the example code: prom is a promise which randomly either resolves with 'Yay!' or rejects with 'Ohhh noooo!'. We pass a success handler to .then() and a failure handler to .catch(). If the promise resolves, .then()'s success handler will be invoked with 'Yay!'. If the promise rejects, .then() will return a promise with the same rejection reason as the original promise and .catch()'s failure handler will be invoked with that rejection reason.

The first handler of .then()

The first handler, sometimes called onFulfilled, is a success handler, and it should contain the logic for the promise resolving.

Pending

The initial state— the operation has not completed yet.

Fulfilled

The operation has completed successfully and the promise now has a resolved value. For example, a request's promise might resolve with a JSON object as its value.

Rejected:

The operation has failed and the promise has a reason for the failure. This reason is usually an Error of some kind.

What if we're dealing with multiple promises, but we don't care about the order? Let's think in terms of cleaning again.

For us to consider our house clean, we need our clothes to dry, our trash bins emptied, and the dishwasher to run. We need all of these tasks to complete but not in any particular order. Furthermore, since they're all getting done asynchronously, they should really all be happening at the same time!

What is an another mistake of promises

Forgetting to return a promise.

const delayedHello = () => { console.log('Hi! This is an asynchronous greeting!'); }; setTimeout(delayedHello, 2000); What does this code do?

Here, we invoke setTimeout() with the callback function delayedHello() and 2000. In at least two seconds delayedHello() will be invoked. After two seconds, delayedHello() is added to a line of code waiting to be run. Before it can run, any synchronous code from the program will run. Next, any code in front of it in the line will run. This means it might be more than two seconds before delayedHello() is actually executed.

Promise.all() accepts an array of promises as its argument and returns a single promise. That single promise will settle in one of two ways:

If every promise in the argument array resolves, the single promise returned from Promise.all() will resolve with an array containing the resolve value from each promise in the argument array. If any promise from the argument array rejects, the single promise returned from Promise.all() will immediately reject with the reason that promise rejected. This behavior is sometimes referred to as failing fast.

In the case of our dishwasher promise, the dishwasher will run then:

If our promise rejects, this means we have dirty dishes, and we'll add soap and run the dishwasher again. If our promise fulfills, this means we have clean dishes, and we'll put the dishes away.

const executorFunction = (resolve, reject) => { if (someCondition) { resolve('I resolved!'); } else { reject('I rejected!'); } } constmyFirstPromise = newPromise(executorFunction); What does this example do?

In our example, myFirstPromise resolves or rejects based on a simple condition, but, in practice, promises settle based on the results of asynchronous operations. For example, a database request may fulfill with the data from a query or reject with an error thrown.

const returnPromiseFunction = () => { return new Promise((resolve, reject) => { setTimeout(( ) => {resolve('I resolved!')}, 1000); }); }; const prom = returnPromiseFunction(); What does this code do?

In the example code, we invoked returnPromiseFunction() which returned a promise. We assigned that promise to the variable prom. Similar to the asynchronous promises you may encounter in production, prom will initially have a status of pending.

returnsFirstPromise() .then((firstResolveVal) => { return returnsSecondValue(firstResolveVal) .then((secondResolveVal) => { console.log(secondResolveVal); }) }) Whats wrong with this code

Instead of having a clean chain of promises, we've nested the logic for one inside the logic of the other. Imagine if we were handling five or ten promises!

What is one mistake of promises

Nesting promises instead of chaining them.

Asynchronous operation

One that allows the computer to "move on" to other tasks while waiting for the asynchronous operation to complete

What can asynchronous operation help with web devolpement?

Operations like making a network request or querying a database can be time-consuming, but JavaScript allows us to execute other tasks while awaiting their completion.

A Promise object can be in one of three states:

Pending, Fufilled, Rejected

We refer to a promise as settled if it is no longer pending— it is either fulfilled or rejected. Let's think of a dishwasher as having the states of a promise:

Pending: The dishwasher is running but has not completed the washing cycle. Fulfilled: The dishwasher has completed the washing cycle and is full of clean dishes. Rejected: The dishwasher encountered a problem (it didn't receive soap!) and returns unclean dishes.

The initial state of an asynchronous promise is pending, but we have a guarantee that it will settle. How do we tell the computer what should happen then?

Promise objects come with an aptly named .then() method. It allows us to say, "I have a promise, when it settles, then here's what I want to happen..."

A description of the reject function:

Reject is a function that takes a reason or error as an argument. Under the hood, if invoked, reject() will change the promise's status from pending to rejected, and the promise's rejection reason will be set to the argument passed into reject().

A description of the resolve function:

Resolve is a function with one argument. Under the hood, if invoked, resolve() will change the promise's status from pending to fulfilled, and the promise's resolved value will be set to the argument passed into resolve().

Asynchronous programming

That time-consuming operations don't have to bring everything else in our programs to a halt.

What does .catch() take as a parameter?

The .catch() function takes only one argument, onRejected. In the case of a rejected promise, this failure handler will be invoked with the reason for rejection.

composition

The process of chaining promises together

the second handler of .then()

The second handler, sometimes called onRejected, is a failure handler, and it should contain the logic for the promise rejecting.

Moving forward, we'll be simulating this by providing you with functions that return promises which settle after some time. How can we do that?

To accomplish this, we'll be using setTimeout().

Let's construct a promise! How can we do that?

To create a new Promise object, we use the new keyword and the Promise constructor method:

How many handlers do we need to invoke .then()

We can invoke .then() with one, both, or neither handler! This allows for flexibility, but it can also make for tricky debugging.

const executorFunction = (resolve, reject) => { if (someCondition) { resolve('I resolved!'); } else { reject('I rejected!'); } } const myFirstPromise = new Promise(executorFunction); Let's break down what's happening above:

We declare a variable myFirstPromise myFirstPromise is constructed using new Promise() which is the Promise constructor method. executorFunction() is passed to the constructor and has two functions as parameters: resolve and reject. If someCondition evaluates to true, we invoke resolve() with the string 'I resolved!' If not, we invoke reject() with the string 'I rejected!'

let myPromises = Promise.all([returnsPromOne(), returnsPromTwo(), returnsPromThree()]); myPromises .then((arrayOfValues) => { console.log(arrayOfValues); }) .catch((rejectionReason) => { console.log(rejectionReason); }); What does this code do?

We declare myPromises assigned to invoking Promise.all(). We invoke Promise.all() with an array of three promises— the returned values from functions. We invoke .then() with a success handler which will print the array of resolved values if each promise resolves successfully. We invoke .catch() with a failure handler which will print the first rejection message if any promise rejects.

To handle a "successful" promise, or a promise that resolved

We invoke .then() on the promise, passing in a success handler callback function

firstPromiseFunction() .then((firstResolveVal) => { return secondPromiseFunction(firstResolveVal); }) .then((secondResolveVal) => { console.log(secondResolveVal); }); What does this code do?

We invoke a function firstPromiseFunction() which returns a promise. We invoke .then() with an anonymous function as the success handler. Inside the success handler we return a new promise— the result of invoking a second function, secondPromiseFunction() with the first promise's resolved value. We invoke a second .then() to handle the logic for the second promise settling. Inside that .then(), we have a success handler which will log the second promise's resolved value to the console. In order for our chain to work properly, we had to return the promise secondPromiseFunction(firstResolveVal). This ensured that the return value of the first .then() was our second promise rather than the default return of a new promise with the same settled value as the initial.

returnsFirstPromise() .then((firstResolveVal) => { returnsSecondValue(firstResolveVal) }) .then((someVal) => { console.log(someVal); }) What's wrong with this code

We invoke returnsFirstPromise() which returns a promise. We invoke .then() with a success handler. Inside the success handler, we create our second promise, but we forget to return it! We invoke a second .then(). It's supposed to handle the logic for the second promise, but since we didn't return, this .then() is invoked on a promise with the same settled value as the original promise!

returnsFirstPromise() .then((firstResolveVal) => { return returnsSecondValue(firstResolveVal) .then((secondResolveVal) => { console.log(secondResolveVal); }) }) Let's break down what's happening in the above code:

We invoke returnsFirstPromise() which returns a promise. We invoke .then() with a success handler. Inside the success handler, we invoke returnsSecondValue() with firstResolveVal which will return a new promise. We invoke a second .then() to handle the logic for the second promise settling all inside the first then()! Inside that second .then(), we have a success handler which will log the second promise's resolved value to the console.

We might make one request to a database and use the data returned to us to make another request and so on! Let's illustrate this with another cleaning example, washing clothes:

We take our dirty clothes and put them in the washing machine. If the clothes are cleaned, then we'll want to put them in the dryer. After the dryer runs, if the clothes are dry, then we can fold them and put them away.

To maximize efficiency we should use concurrency, multiple asynchronous operations happening together. What function should we use?

With promises, we can do this with the function Promise.all()

Does Web development uses asynchronous operation?

Yes

Do the .then have to connect in some way?

Yes, they must connect through the functions or classes.

setTimeout() has two parameters what are they?

a callback function and a delay in milliseconds.

.then()

a higher-order function— it takes two callback functions as arguments

let prom = new Promise((resolve, reject) => { let num = Math.random(); if (num < .5 ){ resolve('Yay!'); } else { reject('Ohhh noooo!'); } }); const handleSuccess = (resolvedValue) => { console.log(resolvedValue); }; const handleFailure = (rejectionReason) => { console.log(rejectionReason); }; prom.then(handleSuccess, handleFailure); Let's break down what's happening in the example code:

prom is a promise which will randomly either resolve with 'Yay!' or reject with 'Ohhh noooo!'. We pass two handler functions to .then(). The first will be invoked with 'Yay!' if the promise resolves, and the second will be invoked with 'Ohhh noooo!' if the promise rejects.

const prom = new Promise((resolve, reject) => { resolve('Yay!'); }); const handleSuccess = (resolvedValue) => { console.log(resolvedValue); }; prom.then(handleSuccess); // Prints: 'Yay!' Break down this code.

prom is a promise which will resolve to 'Yay!'. We define a function, handleSuccess(), which prints the argument passed to it. We invoke prom's .then() function passing in our handleSuccess() function. Since prom resolves, handleSuccess() is invoked with prom's resolved value, 'Yay', so 'Yay' is logged to the console.

Example of .catch()

promiseAdd(ice).then(success).catch(failure)

Promise composition allows for much more of what?

readable code than the nested callback syntax that preceded it.

The executor function has two function parameters, what are they?

resolve() and reject() functions.

When the promise settles

the appropriate handler will be invoked with that settled value.

Asynchronous JavaScript uses something called

the event-loop

With typical promise consumption, we won't know whether a promise will resolve or reject, so what do we need to provide

the logic for either case. We can pass both a success callback and a failure callback to .then().

This delay is performed asynchronously. What does that do to our code?

the rest of our program won't stop executing during the delay.

When done correctly, promise composition is a great way to what?

to handle situations where asynchronous operations depend on each other or execution order matters.

Instead of passing both handlers into one .then()

we can chain a second .then() with a failure handler to a first .then() with a success handler and both cases will be handled.


Related study sets

Types of Insulin and their Action (onset, peak, and duration)

View Set

Module 6 Reading Assignment - Medications and Special Diets

View Set

HOA - Wright Chapter 4: The Diplomatic Role of the USA in the Second World War, 1941-1945

View Set