Synchronous code has one sequential execution path, and when the long-running code is executing, nothing else can be accomplished.
Long running operations should be implemented as asynchronous operations (a seperate execution path) to make the UI more responsive.
The pattern for working with asynchrony is to use a promise object. The promise (also known as a future or deferred) object provides a mechanism to schedule work to be done on a value that might not yet be computed. The promise object can be in one of three states: pending, resolved, or rejected. It starts in the pending state, moves to either resolved or rejected, and then does not change