Created
March 22, 2018 10:43
-
-
Save jonurry/29fc4bf7b85d103b7842090deba86fd3 to your computer and use it in GitHub Desktop.
11.1 Tracking The Scalpel (Eloquent JavaScript Solutions)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // my solution | |
| async function locateScalpel(nest) { | |
| let results = network(nest).map(async name => { | |
| // if the name of the nest that was last known to hold the scalpel | |
| // is the current nest then we have found the scalpel | |
| // else, return null | |
| if (name === await anyStorage(nest, name, 'scalpel')) { | |
| return name; | |
| } else { | |
| return null; | |
| } | |
| }); | |
| // get the name of the nest that is not null | |
| return (await Promise.all(results)).filter(nest => nest !== null)[0]; | |
| } | |
| // official answer | |
| async function locateScalpel(nest) { | |
| let current = nest.name; | |
| for (;;) { | |
| let next = await anyStorage(nest, current, "scalpel"); | |
| if (next == current) return current; | |
| current = next; | |
| } | |
| } | |
| // my solution without async/await, just a promise | |
| function locateScalpel2(nest) { | |
| // recursively search nests until scalpel is found | |
| function findScalpel(nextNest) { | |
| // check nextNest for scalpel | |
| return anyStorage(nest, nextNest, 'scalpel') | |
| .then(value => { | |
| if (value == nextNest) { | |
| // found scalpel | |
| return value; | |
| } else { | |
| // continue search from last nest known to contain scalpel | |
| return findScalpel(value); | |
| } | |
| }); | |
| } | |
| // start search at current nest | |
| return findScalpel(nest.name); | |
| } | |
| // oficial answer | |
| function locateScalpel2(nest) { | |
| function loop(current) { | |
| return anyStorage(nest, current, "scalpel").then(next => { | |
| if (next == current) return current; | |
| else return loop(next); | |
| }); | |
| } | |
| return loop(nest.name); | |
| } | |
| locateScalpel(bigOak).then(value => console.log('1st:', value)); | |
| // → Butcher Shop | |
| locateScalpel2(bigOak).then(value => console.log('2nd:', value)); | |
| // → Butcher Shop |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hints
This can be done with a single loop that searches through the nests, moving forward to the next when it finds a value that doesn’t match the current nest’s name and returning the name when it finds a matching value. In the
asyncfunction, a regularfororwhileloop can be used.To do the same in a plain function, you will have to build your loop using a recursive function. The easiest way to do this is to have that function return a promise by calling
thenon the promise that retrieves the storage value. Depending on whether that value matches the name of the current nest, the handler returns that value or a further promise created by calling the loop function again.Don’t forget to start the loop by calling the recursive function once from the main function.
In the
asyncfunction, rejected promises are converted to exceptions byawait. When anasyncfunction throws an exception, its promise is rejected. So that works.If you implemented the non-
asyncfunction as outlined above, the waythenworks also automatically causes a failure to end up in the returned promise. If a request fails, the handler passed tothenisn’t called, and the promise it returns is rejected with the same reason.