Skip to content

Instantly share code, notes, and snippets.

@jonurry
Created March 22, 2018 10:43
Show Gist options
  • Select an option

  • Save jonurry/29fc4bf7b85d103b7842090deba86fd3 to your computer and use it in GitHub Desktop.

Select an option

Save jonurry/29fc4bf7b85d103b7842090deba86fd3 to your computer and use it in GitHub Desktop.
11.1 Tracking The Scalpel (Eloquent JavaScript Solutions)
// 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
@jonurry
Copy link
Copy Markdown
Author

jonurry commented Mar 22, 2018

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 async function, a regular for or while loop 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 then on 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 async function, rejected promises are converted to exceptions by await. When an async function throws an exception, its promise is rejected. So that works.

If you implemented the non-async function as outlined above, the way then works also automatically causes a failure to end up in the returned promise. If a request fails, the handler passed to then isn’t called, and the promise it returns is rejected with the same reason.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment