loading...
Cover image for `throw` objects and functions

`throw` objects and functions

aravindballa profile image Aravind Balla ・1 min read

Did you know you could throw objects/functions in Javascript? Objects mean, useful objects for the program to run, not only useful for debugging. Here's a very short one for you!

Lets look at simple code demonstrating a not-at-all-useful cache.

    const cache = new Map();

    const read = key => cache.get(key);

    const store = (key, value) => {
      cache.set(key, value);
    }

    const fakeExternalRes = key => Math.random(0, 888);

    const readResource = async key => {
      let value;

      // try reading from cache
      // if not found, fetch it from external resource
      try {
        value = read(key);
        if(!value) throw key;
      } catch (key) {
        value = fakeExternalRes(key);
        store(key, value);
      }

      return value;
    }

    store('asdf', 'world');
    console.log(readResource('hello'));
    console.log(readResource('hello'));

/*
Output:
0.4123278447585672
0.4123278447585672
*/

Here, we threw the key and caught it to actually fetch it from external resource and store in the cache. Kinda cool way.

One gotcha here is, we generally use throw for exceptions and not in normal good case scenarios. So we have to make sure that we don't disturb that mindset for fellow members in the team.

This is used in react-cache package by the Facebook team. I have just demonstrated a very simple thing with this. But you can check out the below link for how they have implemented.

https://github.com/facebook/react/blob/master/packages/react-cache/src/ReactCache.js#L281-L305

Take care.

Posted on by:

aravindballa profile

Aravind Balla

@aravindballa

Never not learning. When not writing code πŸ‘¨πŸ»β€πŸ’», he is climbing a mountain πŸ§—β€β™‚οΈ or writing ✍️ or recording a podcast πŸŽ™ or drinking coffee β˜•οΈ

Discussion

pic
Editor guide
 

One gotcha here is, we generally use throw for exceptions and not in normal good case scenarios.

Ruby distinguishes the two use cases as begin/rescue (error handling) and throw/catch (control flow, i.e. exiting a nested loop).

The problem with your example is that the throw/catch construct is easily replaceable with a normal if statement. The actual React code you linked has no catch anywhere near the throw, so it will unwind the stack until it encounters the appropriate handler, something that is not easily achievable with a normal return statement (baring tuple returns and manual propagation of the same up the call stack).

 

That doesn't have a catch. But it handles it in the then part.

github.com/facebook/react/blob/mas...

 

Sure, but that's still very different from your example, which could have been just this:

let value;

// try reading from cache
// if not found, fetch it from external resource
value = read(key);
if (!value) {
  value = fakeExternalRes(key);
  store(key, value);
}

return value;

I understand that examples need to be simplified, I just feel that yours got simplified to the point where it's not actually showing what you intended to anymore.