Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

progress notifications in ECMAScript Promise

We're using ECMAScript 6 promises.

We need to implement progress notifications to the end-user (this is pure UX requirement). I know that other promise frameworks (Q promise library, for ex.) allows that.

How can we adopt some kind of progress indication most elegantly?

Or should we migrate to a different framework? (I don't know how to estimate the effort of the latter)

like image 525
Assaf Shemesh Avatar asked Oct 02 '15 14:10

Assaf Shemesh


People also ask

How are promises executed in JavaScript?

The Promise constructor takes a function (an executor) that will be executed immediately and passes in two functions: resolve , which must be called when the Promise is resolved (passing a result), and reject , when it is rejected (passing an error).

What is Promise ES6?

ES6 Promise is the easiest way to work with asynchronous programming in JavaScript. Asynchronous programming includes the running of processes individually from the main thread and notifies the main thread when it gets complete. Prior to the Promises, Callbacks were used to perform asynchronous programming.

In what version of ECMAScript were promises added?

Promises are a way to implement asynchronous programming in JavaScript(ES6 which is also known as ECMAScript-6).

What are the types of promises in JavaScript?

A Promise is in one of these states: pending: initial state, neither fulfilled nor rejected. fulfilled: meaning that the operation was completed successfully. rejected: meaning that the operation failed.


2 Answers

ES2015 promises will never have progression. Promises represent a singular eventual value. If you want multiple values you can look into observables - or put the progress on the promise returning function.

Putting the progress on the promise returning function is pretty easy. Basically you take a callback as a parameter to the function and call it whenever a progress notification should happen.

Here is some text adapted from our guide at bluebird:

Progression has composability and chaining issues with APIs that use promise progression handlers. As other libraries move away from the progression API since it really has little to do with promises, so will Bluebird. Implementing the common use case of progress bars can be accomplished using a pattern similar to IProgress in C#.

Using jQuery before:

Promise.resolve($.get(...))     .progressed(function() {         // ...     })     .then(function() {         // ...     })     .catch(function(e) {         // ...     }) 

Using jQuery after:

Promise.resolve($.get(...).progress(function() {         // ...     }))     .then(function() {         // ...     })     .catch(function(e) {         // ...     }) 

Implementing general progress interfaces like in C#:

function returnsPromiseWithProgress(progressHandler) {     return doFirstAction().tap(function() {         progressHandler(0.33);     }).then(doSecondAction).tap(function() {         progressHandler(0.66);     }).then(doThirdAction).tap(function() {         progressHandler(1.00);     }); }  returnsPromiseWithProgress(function(progress) {     ui.progressbar.setWidth((progress * 200) + "px"); // update with on client side }).then(function(value) { // action complete    // entire chain is complete. }).catch(function(e) {     // error }); 
like image 199
Benjamin Gruenbaum Avatar answered Sep 20 '22 17:09

Benjamin Gruenbaum


Since only specific instance of promise generates progress, we can monkey patch it on demand, like this:

   function reparse(){         let notify         let promise = new Promise(async(resolve,reject)=>{             instanceOfjQueryDeferred.done(()=>{                 resolve(100)             }).progress((progress)=>{                 notify(progress)             })         })         // here is the monkey patch         promise.progress  = (handler)=>{             notify = handler             return promise         }         return promise     } 

And use it like this:

reparse().progress((p)=>{     console.log('progress',p) }).then((progress)=>{     console.log('done',progress) }) 
like image 24
Singuan Iap Avatar answered Sep 19 '22 17:09

Singuan Iap