@@ -110,7 +110,36 @@ Now we have the same 1 -> 2 > 4 output, but with 1 second delay between each.
110110
111111When we return ` new Promise(…) ` , the next ` .then ` in the chain is executed when it settles and gets its result.
112112
113- Let's use it to ` loadScript ` multiple scripts one by one:
113+ Let's use it with ` loadScript ` to load multiple scripts one by one, in sequence:
114+
115+ ``` js run
116+ loadScript (" /article/promise-chaining/one.js" )
117+ .then (function (script ) {
118+ return loadScript (" /article/promise-chaining/two.js" );
119+ })
120+ .then (function (script ) {
121+ return loadScript (" /article/promise-chaining/three.js" );
122+ })
123+ .then (function (script ) {
124+ // use variables declared in scripts
125+ // to show that they indeed loaded
126+ alert (" Done: " + (one + two + three));
127+ });
128+ ```
129+
130+
131+ The code totally evades the pyramid of doom. We can add more asynchronous actions to the chain, and the code is still "flat".
132+
133+ ## Error handling
134+
135+ In case of an error, the closest ` onRejected ` handler down the chain is called.
136+
137+ Let's recall that a rejection (error) handler may be assigned with two syntaxes:
138+
139+ - ` .then(...,onRejected) ` , as a second argument of ` .then ` .
140+ - ` .catch(onRejected) ` , a shorthand for ` .then(null, onRejected) ` .
141+
142+ In the example below we use the second syntax to catch all errors in the script load chain:
114143
115144``` js run
116145function loadScript (src ) {
@@ -119,13 +148,17 @@ function loadScript(src) {
119148 script .src = src;
120149
121150 script .onload = () => resolve (script);
122- script .onerror = () => reject (new Error (" Script load error: " + src));
151+ * ! *
152+ script .onerror = () => reject (new Error (" Script load error: " + src)); // (*)
153+ */ ! *
123154
124155 document .head .append (script);
125156 });
126157}
127158
128- loadScript (" /article/promise-chaining/one.js" )
159+ * ! *
160+ loadScript (" /article/promise-chaining/ERROR.js" )
161+ */ ! *
129162 .then (function (script ) {
130163 return loadScript (" /article/promise-chaining/two.js" );
131164 })
@@ -136,10 +169,53 @@ loadScript("/article/promise-chaining/one.js")
136169 // use variables declared in scripts
137170 // to show that they indeed loaded
138171 alert (" Done: " + (one + two + three));
172+ })
173+ * ! *
174+ .catch (function (error ) { // (**)
175+ alert (error .message );
139176 });
177+ */ ! *
140178```
141179
142- The code totally evades the pyramid of doom. We can add more asynchronous actions to the chain, and the code is still "flat".
180+ In the code above the first ` loadScript ` call fails, because ` ERROR.js ` doesn't exist. The initial error is generated in the line ` (*) ` , then the first error handler in the chain is called, that is ` (**) ` .
181+
182+ Now the same thing, but the error occurs in the second script:
183+
184+
185+ ``` js run
186+ loadScript (" /article/promise-chaining/one.js" )
187+ .then (function (script ) {
188+ * ! *
189+ return loadScript (" /article/promise-chaining/ERROR.js" );
190+ */ ! *
191+ })
192+ .then (function (script ) {
193+ return loadScript (" /article/promise-chaining/three.js" );
194+ })
195+ .then (function (script ) {
196+ // use variables declared in scripts
197+ // to show that they indeed loaded
198+ alert (" Done: " + (one + two + three));
199+ })
200+ * ! *
201+ .catch (function (error ) {
202+ alert (error .message );
203+ });
204+ */ ! *
205+ ```
206+
207+ Once again, the ` .catch ` handles it.
208+
209+ ** Throwing an exception is also considered an error.**
210+
211+ For instance:
212+
213+ ``` js run
214+ new Promise (function (resolve , reject ) {
215+ throw new Error (" Woops!" );
216+ }).catch (function (error ) {
217+ alert (error .message ); // Whoops
218+ });
143219
144220## Inheriting from promise, thenables, error handling?
145221
0 commit comments