2

I am using JS Promise to refactor our JS API. However I met a problem which stops me from going further.

Basically, one of our API is to issue a async GET request and download a large file.

So the usage of the API would like this:

var callback = { success: function(data){...}, failure: function(data){...} } Test(token).download(url).then(callback.success, callback.failure); 

The Test function makes a XHR request to the url and calls the callback functions in onload & onerror event handlers.

The problem is during the download procedure, the UI needs to be refresh, i.e. the progress bar, which is handled in onprogress.

The callback.success will only be called once when the Promise is resolved. So how should I implement the UI refresh callback which should be called in onprogress event handler of the inner XHR component of Test function?

2
  • Create multiple independent promises. Commented Apr 20, 2016 at 7:27
  • @zerkms But I only want to issue one download request and download one file. Commented Apr 20, 2016 at 7:42

2 Answers 2

4

Promises are simply not a good architectural match for multiple progress notifications. Promises are a one-way state machine meant to communicate completion or error - that's really all they are designed for. They do not have any mechanism built-in for doing multiple progress notifications.

Instead, for progress notifications, you should some other architectural mechanism such as a regular callback that is called each time or an eventEmitter that triggers multiple progress events.

In the scheme you've shown so far, it would probably look like this:

var callback = { success: function(data){...}, failure: function(data){...}, progress: function(data){...} } Test(token).download(url, callback.progress).then(callback.success, callback.failure); 

Then, inside your download() function, you call the progress callback as many times as appropriate.


Personally, I think it would be more useful to your callers if you just returned the promise and let them supply resolve and reject handlers themselves rather than hiding the promise and making your callers live with the year 2013 callback architecture. Returning the promise allows them to use all the promise features such as chaining, aggregation with other promises, error propagation in their own code, etc...

So rather than passing in a callback object with multiple callbacks, all they pass in is the progress callback and you return back a promise. The caller can then attach their own resolve and reject handlers on the returned promise. It's 2016 and promises are standardized in ES6. There's no need to hide them from your callers and there's every reason to return the promise so your callers can tap into the benefits of promises too.

Sign up to request clarification or add additional context in comments.

2 Comments

Actually I am using the XMLHttpRequest Promise example on developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
@deepsky - Well, I don't agree with how that example works. In these times with promises standardized, you may as well just return the promise to your caller and let them have the benefits of using promises. You're cutting out 80% of the benefit of using promises by not letting your caller use a returned promise.
1

Since promises in JavaScript are only state-machine, it is not possible to get the progress of the promise. You would have to use other means.

See this article for example: progress notifications in ECMAScript Promise

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.