 By this point, you should have been using promises to fetch files and work with a service worker. I gave you a quick introduction in the Core Technologies presentation. But using then and catch just scratches the surface of promises. Let's go deeper. Remember that promises are designed to make asynchronous programming easier. They replace nested callbacks like this with the then and catch functions. Your code becomes easier to read and error handling becomes much simpler. Here's the same code using promises. One thing that may not be apparent here is that the value returned from each function is passed to the next one. So the result of get image name is passed to fetch flag. The result of fetch flag is passed to append flag and so on. If you're familiar with Unix pipes, this is the same idea. Note that you return a single value and each function accepts a single parameter. This may seem limiting, but it works well in practice. Now let's add some error handling. All of our examples so far have put the catch at the end, but you can have more than one catch. Each catch will intercept errors for the calls above it and will continue execution with the next then. In this case, the first catch intercepts errors fetching the image name and substitutes an alternate name, possibly a no-image symbol. The catch at the end intercepts any errors above it and logs the error. You might re-throw the exception to let whoever calls this code know about the error. We've been using promises generated by fetch and the service worker, but you can create your own. Normally, you would use this to wrap a callback or event-based function. Here's an example using a callback-based function. DoAsync thing takes a callback with a result and we want to convert it into a promise. First, create a promise object. It takes a function with two callbacks named resolve and reject. Inside the function body, call your asynchronous function. In this case, doAsync thing. If it returns successfully, call resolve with the result of the asynchronous function. If it fails, call reject with the error. This might seem like a lot of work just to wrap up a callback, but you can handle more complex cases such as code that returns events. In practice, a little work wrapping asynchronous code in promises yields smaller, more maintainable programs. We stored the promise in the variable p so we can now use a regular then and catch chain. So far, we're processing things one at a time, fetching single files and the like. What if you want to do these fetches in parallel? You can use promise.all to run multiple promises concurrently. Promise.all takes an array of promises and returns a single promise when they all resolve or when one of them rejects. This result will either have an array of results or the reason for the rejection. Note that even if an input promise rejects, causing promise.all to reject, the remaining promises still run and the results will be discarded. At the time of this filming, there's no way to cancel a promise, though it's under discussion. You might want to run multiple promises and take the first result to come in. Promise.race lets you do that. It also takes an array of promises and resolves or rejects with whatever promise settles first. This behavior causes an unexpected problem. Let's say you have two promises, a slow one that resolves eventually and a fast one that rejects immediately. The fast one will always win. That's a problem because you may be taking two paths to the same resource. In that case, you really want to wait for the first promise that resolves, not just the first one that settles. This happens more often than you think. Your service worker might want to try both the network and the cache at the same time. But if this isn't in the cache or if the network is down, the race will fail even though the other location might have the resource. The only answer here is to write your own race function if you don't like the current behavior. Jake Archibald's offline cookbook includes a replacement race function in ten lines of code including comments. Now it's your turn. Go to the promises lab. In there, you will practice wrapping calls and promises, chaining them together and catching errors. You'll also get to experiment with running promises in parallel. Have fun and good luck. One last thing. If you're an instructor, this final slide links to more information on promises. If you're a student, these links can be found in your textbook. You may want to use these while you're working on the lab.