Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor changes to article 37 #87

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 13 additions & 14 deletions 37 - Working with Multiple Promises.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ The last example we 'stepped', which is to say that we waited for the post to co

In some cases, you just want to fire them all off at the exact same time, because they're not dependent on each other, and you want to get two things back, or four things back, as soon as possible.

I've got an example for `weather`, where I'm going to fetch the weather, and it's going to come back after two seconds, 2000 milliseconds, with a temperature of 29, Sunny With Clouds.
I've got an example for `weather`, where I'm going to fetch the weather, and it's going to come back after two seconds, 2000 milliseconds, with a temperature of 29, Sunny with Clouds.

Then I also want to go get my `tweets`. I'm not searching for tweets based on weather or anything like that. The tweets have nothing to do with the weather, other than I just need to get these two pieces of data. This comes back after 500 milliseconds, half a second.
I also want to get my `tweets`. I'm not searching for tweets based on the weather or anything like that. The tweets have nothing to do with the weather, I just need to get both pieces of data. The tweets reqest comes back after 500 milliseconds, half a second.


```js
Expand All @@ -21,7 +21,7 @@ const tweets = new Promise((resolve) => {
});
```

The way that we can do that, instead of chaining `.thens` together, we can say `Promise.all`, and you pass it an array of `promise`s, so in this case, `weather` and `tweets`, and you call `.then` against that. Then when that comes back, we are going to get our `responses`.
The way that we can do that, instead of chaining `.then` together, we can use `Promise.all`, and you pass it an array of `Promises`. In this case `weather` and `tweets`, and call `.then` against that. When both `Promises` resolve we are going to get our `responses`.

```js
const weather = new Promise((resolve) => {
Expand All @@ -45,7 +45,7 @@ Promise
```
[2:04]

In the console, you should notice that it takes two seconds to come back. This is because every `Promise` in the function has to finish before we can run the `.then` to get a result. In this case, our longest `promise` takes two seconds. So for example, if a `promise` takes takes 10 seconds, your `Promise.all` is going to take 10 seconds to resolve. If one takes 15 seconds, it's going to take 15 seconds. The slowest response decides how long these things should actually take.
In the console, you should notice that it takes two seconds to come back. This is because every `Promise` in the function has to finish before we can run the `.then` to get a result. In this case, our longest `Promise` takes two seconds. So for example, if a `Promise` takes 10 seconds, your `Promise.all` is going to take 10 seconds to resolve. If one takes 15 seconds, it's going to take 15 seconds. The slowest response decides how long these things should actually take.

In our case, the console should return an array of `[Object, Array[2]]`, where the first item in the array is our `weather` object, `"Sunny with Clouds"` and `temp: 29`, and our second item is our array of `tweets`.

Expand All @@ -63,7 +63,7 @@ Promise

Now, we have two separate variables, one with our `weather`, one with our `tweets` in it, and we can go ahead and start populating the data on our actual home page.

However, it's probably not a good idea to name this `weather` and `tweets`. Why? Because our `promises` are named `weather` and `tweets`, so maybe call it `weatherInfo` and `tweetsInfo`.
However, it's probably not a good idea to name this `weather` and `tweets`. Why? Because our `Promises` are named `weather` and `tweets`, so maybe call it `weatherInfo` and `tweetsInfo`.


Let's actually do some with some real data here.
Expand All @@ -75,9 +75,9 @@ const postsPromise = fetch('http://wesbos.com/wp-json/wp/v2/posts');
const streetCarsPromise = fetch('http://data.ratp.fr/api/datasets/1.0/search/?q=paris');
```

I've got `postPromise` here, which is going to go to my blog and grab all of my latest posts, which I've used before. We also have the `streetCarsPromise`, which is going to go and fetch some data from the Paris transit system.
I've got `postsPromise` here, which is going to go to my blog and grab all of my latest posts, which I've used before. We also have the `streetCarsPromise`, which is going to go and fetch some data from the Paris transit system.

We need to resolve each `promise`, or rather, they will resolve themselves, but we need to listen to when they are both resolved.
We need to resolve each `Promise`, or rather, they will resolve themselves, but we need to listen to when they are both resolved.

```js
const postsPromise = fetch('http://wesbos.com/wp-json/wp/v2/posts');
Expand All @@ -97,7 +97,6 @@ I actually have a `browser-sync` command I use to do this from the directory I'v

You can get `browser-sync` if you don't already have a way of spinning up a server, and you can get it by typing `npm install -g browser-sync` in your terminal to install it as a global package.


So once you get that all going, let's go ahead and take a look at our console for `responses`, which we'll find is an array of two things.

We got the first response that comes back from Wesbos.com, and we got the second response that comes back from the Paris transit system but we don't see the data in our `body`... we actually have a problem where we have to convert a readable stream into json, right? This is the problem we had on the first example.
Expand All @@ -115,17 +114,17 @@ Promise.all([postsPromise, streetCarsPromise])
```


What we can do is we can return a promise.all again, and then we will take each of these things, which is the responses, and we can just map over them and call .json on each one.
What we can do is we can return a `Promise.all` again, and then we will take each of these things, which is the `responses`, and we can just map over them and call `.json` on each one.

We'll say response, and we will return response.json. Why do we have to call this res.json? Why can't we just say json.parse around, res.body or something like that?
We'll say response, and we will return response.json. Why do we have to call this `res.json`? Why can't we just say `JSON.parse` around, `res.body` or something like that?

We actually use `res` instead of `responses` here, because there are many different types of data that could come back. If you [check out the documentation on MDN](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch), you can see that the data can come back as an `.arrayBuffer()`, `.blob()`, `.json()`, `.text()`, or `.formData()`.

Don't just assume that your APIs or your AJAX requests are always going to be json, because it could be any of those data types.

What are we doing? Our response is, in this case, in an array, and `.map` takes every item out of an array, does something to it, and then returns a new array.

What we're doing here, is we're taking the array of `responses` and taking each one and calling `.json()` on it. This returns a second promise, which we can call `.then` on, and that should then, responses, that should give us some real data:
What we're doing here, is we're taking the array of `responses` and taking each one and calling `.json()` on it. This returns a second `Promise` which can call `.then` on. This `.then` will finally give us the real data as, named here as `parsedResponses`:

```js
const postsPromise = fetch('http://wesbos.com/wp-json/wp/v2/posts');
Expand All @@ -135,10 +134,10 @@ Promise.all([postsPromise, streetCarsPromise])
.then(responses => {
return Promise.all(responses.map(res => res.json()))
})
.then(responses => {
console.log(responses);
.then(parsedResponses => {
console.log(parsedResponses);
})
```
So if we open this up, we'll see our API data in an array. In this case, we got about 10 posts, and an object containing some information about the Paris transit system.

So what we've done overall here is using a `Promise.all` on our initial promises, `postsPromise` and `streetCarsPromise`. Then when both of those promises come back, we run `.json()` on all of them. Then, when both of those come back from being turned from just regular data into json, which is instant, then this final `promise` then is called and we can do whatever it is that we want with that data.
So what we've done overall here is using a `Promise.all` on our initial promises, `postsPromise` and `streetCarsPromise`. Then, when both of those promises come back, we run `.json()` on all the `responses`. Then, when both of those come back from being turned from just regular data into json, which is instant, the final `then` is called. This finally gives us the data so we can do whatever it is that we want with it.