Javascript Weekly Digest #2

At work, the team gets together once a week to share stuff we’ve learn, interesting posts and go over some of the highlights from the javascript world.
I’ll try to share a summary of the things we covered each week.
Here you can find the first post in the series.

This week we’ve talked about ‘React Storybook’ and ‘Asynchronous patterns in javascript’.


React Storybook

React Storybook is a UI development environment for react component.
It enable you to visualize components in isolation, in different states. It also enables, through set of add-ons, a great way to interact with the component, change its props, view events, documentation, and run tests

In a recent project, we decided to build things bottom-up. 
We started by creating the UI components for the whole project, implemented the design and behavior for each component.
We used React-Storybook as a catalog of the component, helping us visualize and interact with the components as we create them, giving us fast feedback-loop.
We were also able to publish this storybook to other people in the company (such as Product Managers / UI / UX / QA), let them interact and feel the component, and give us comments in early stages of the development.

After we basically finished building and iterating over the presentational components, we were now able to continue building up, assemble them together into a complete application.

Because of the workflows it enables, one of the team members described this tool as ‘Swagger for UI Components’.

There is a good intro on react-storybook in this post, and also the documentation on the site is very informative.
Introducing storybook into either a new or existing project is a matter of minutes, using ‘getstorybook’ CLI.
It also detect if the project was created using create-react-app and integrate with it nicely.

Storybook supports add-ons which add extra features.
There are some built-in and some third-party add-ons, and you can of-course create your own.
You can find list of the add-ons in the add-ons gallery page.
We found ‘Actions’ and ‘Knobs’ add-ons to be very useful for our needs.

Asynchronous Patterns in Javascript

Callbacks, Promises, Iterators, Iterable, Generators, Async-Await

Javascript has evolved and introduce better patterns and structures for dealing with asynchronous operation.

Callbacks
In this approach, we’re passing a callback-function as a parameter when invoking another asynchronous function.
The asynchronous function will call our callback-function when the operation finish, and optionally pass value to it.
There are a lot of examples for this usage even in the native browser/node APIs — e.g. setTimeout.

Here is an example of code the use the ‘request’ library to issue an http request. The request() function receive callback which will be called with the network request result:

Nesting multiple operations, chaining values from one to another and dealing with errors gets cumbersome when dealing with callbacks.

Promises
The promise object come to solve these problems, it provide an interface that detach the asynchronous operation from its consumers.

Now the asynchronous function can produce a new Promise instance.
Promise is an object which represent a value which might be already available, or will be available in the future, or never.
Using methods like .then() and .catch(), the consumer of this value can subscribe to receive the value when it’s ready, or an error if something occurred.

So the same code above can be rewritten using promises like this:

You can also take function that has callback argument and wrap them with promise.
For example, we can wrap setTimeout function to create a new delay function that return a promise that will be resolved after given time.

Another example — we can wrap fs.readFile to create a new readFileAsync function which will return a Promise which will resolved with the file content.

We can also use Promise.race() and Promise.all(), both of these function receive an array of promises as argument and return a new Promise.

From the Promise MDN page:

Promise.race will return a Promise that fulfills or rejects as soon as one of the promises in the iterable fulfills or rejects, with the value or reason from that promise.

Promise.all returns a promise that either fulfills when all of the promises in the iterable argument have fulfilled or rejects as soon as one of the promises in the iterable argument rejects.

Iterators

Iterator is an object with next function that return object { value, done }.

For example, here we have a function that create an iterator that calculate the next fibonacci number on every call to .next(), until it reach the number specified in the argument.

Iterable

Object that implement an iterator method, under a property with Symbol.iterator.

In the above code, fib object is an iterable, because it define an Symbol.iterator property which is value is a function that create an iterator.

For iterable objects, we can use for..of and spread operator to iterate on their values:

Generator

A generator object is both, iterator and iterable.

To create a generator, we can define a function using the function* syntax.
Inside such function, we can use the yield expression to pause and resume the generator function.
We can also use it to return value to the caller and to receive value from it.

Here is a sample of a simple generator function that return ‘bar’ the first time it gets called and ‘baz’ the second time.

We can also define a function that keep generating new values.
We’ll use the fibonacci example once again, this time as generator:

Notice few things here — 
1. we are using “while (true)”, so as long as we keep calling the function it will keep returning another value. This iterator never gets into { done: true } state.

2. we call “yield current”, which will return the current number to the caller.

3. we also assign a value returned from the yield expression into a reset variable.
The caller can choose to call the generator .next() function and pass it a value. In this case, if it will be called with .next(true), the numbers will reset and the generator will start counting from the start.

It is also possible to call .throw() on the generator function.
In this case an exception will be thrown and from now on every call to .next() will return object { value: undefined, done: true }.

async-await

Async functions simplify the way of using promises. It combine the power of both promises and generators, and enable you to chain asynchronous operations in a way that read like synchronous code.

We use the await keyword inside an async function to indicate that we are running an awaitable (Promise) object. When that promise gets resolve, its value gets unwrapped by the await keyword, and the execution resume from the same place in the function (similar to how yield works in generator function).

Async function itself return a Promise, so you can also chain multiple async functions.

In the above example we define an async function named ‘foo’, when we execute the code it will:
- Immediately print ‘starting
- Start a promise that will be resolve in 1 second.
at this point, the function is “paused” and the thread is not blocked.
If there are other things that should be running, like request handlers or timers, they can execute.
- When the promise is resolved, the execution of the function resume, and it will now print ‘finish’.
- The return statement actually resolves the promise made when foo() was executed with the value “bar”.
- The .then() handler is called asynchronously after the current thread of execution finishes and it will print “bar” to the console.


While creating the presentation for the team and while making this blog post, I relied on examples from this talk.

And from the MDN pages on Promises, Iterators and generators.