Pardon my coffeescript, but this is what I do. I basically defined
BatchRequest.get(url) that returns a promise to resolve just like $http.get
(I only package up get requests). BatchRequest will set a timeout for 50 ms
and collect all the gets it receives in those 50ms and post them in one big
request to my batch handler backend. The specifics of the batch request are
implementation-bound, bassmaster expects me to post to its endpoint with a
JSON array of request objects.
This way, any time I might instead do $http.get I do BatchRequest.get.
I *also* have reimplemented some promise-unwrapping style stuff in my ORM
using javascripts ability to do get/set functionality. Basically, the
getter for something like document.title will either return the document's
title (if it has been loaded and resolved) *or* it will kick off a
BatchRequest.get for the resource and return '' in the meantime. This leads
to some flickering as resources load on the page, but I find it's a nice
compromise - this way I don't have to muck around with manually
side-loading stuff. Document.find(1) will return right away and show up on
the page, and it will be JIT loaded in the event that angular actually
paints the screen with it (helpful for stuff like lazy-loading and
infinite-scrolling).
So what tends to happen is that the user hits a route on angular, the
top-level object (say, conversations/1) loads with a regular $http.get, but
then a lot of the other stuff (profile objects for editors of the document,
reaction events for people agreeing / disagreeing, etc) all get painted in
their undefined state, trigger a BatchRequest, and then 50 ms later a big
batch request goes to the backend for processing.
Tangentially, I'm thinking about cacheing resources in localStorage
whenever possible, and I've also explored using websockets as a kind of
pseudo-spdy kind of thing to get resources. My application loads a lot of
data, but well over 80% of it doesn't change on a visit-to-visit basis (a
user *could* edit /documents/1 or /profiles/1, but they don't do that all
too often - far more common is adding a new reply or agree-er). So I could
do something like stash stuff in localStorage, ping the websocket with "hey
I just loaded this" events, and then the backend could dribble out updates
when needed. I'm already most of the way there for that kind of pattern,
mostly, I need to worry about garbage-collecting and cache expiry in
localStorage, because nothing says awesome like monotonically increasing
storage requirements.
angular.module 'clientApp.apiModel.batchRequest', ['ng'].service
'BatchRequest', ($q, Server, $http, $timeout)->
timeoutPromise = undefined
queue = []
postBatch = ->
requestQueue = queue.map (req)-> {method: 'GET', path: req.url,
deferred: req.deferred}
queue = []
timeoutPromise = undefined
$http
method: 'POST'
url: "#{Server.api}/api/batch"
data:
requests: requestQueue.map (i)->{method: i.method, path: i.path}
.then (data)->
requestQueue.forEach (val, i)-> #bassmaster returns an array in
the same order as the request
if data.data[i].statusCode? #statusCode only exists if there
was an error on that subrequest
val.deferred.reject(data.data[i])
else
val.deferred.resolve(data.data[i])
get: (url)->
unless timeoutPromise?
timeoutPromise = $timeout postBatch, 50
deferred = undefined
queue.forEach (thing)->
if thing.url == url #this just makes sure we're not already
asking for the same resource
deferred = thing.deferred
unless deferred?
deferred = $q.defer()
queue.push
url: url
deferred: deferred
return deferred.promise
On Thu, Sep 18, 2014 at 9:30 AM, Rob Koberg <[email protected]> wrote:
> Hi Sander,
>
> You wrote:
>
> "Bundling requests is most of the time a good idea. It's a bit more work
> on the client, but if your app is going to be run on a high-latency
> network (mostly mobile) it is a big plus
> for your application."
>
> How are you doing this on the client? I have been "bundling" on the
> server and use one request from the client (using a route resolve to
> get the data).
>
> On Thu, Sep 18, 2014 at 9:08 AM, 'Michael Bielski' via AngularJS
> <[email protected]> wrote:
> > FWIW, when I first learned BASIC in high school we did not have screens.
> It
> > was all done on teletype-like terminals that saved your program on paper
> > tape. After that I bought an Atari 800XL and really thought I was stylin!
> >
> > --
> > You received this message because you are subscribed to the Google Groups
> > "AngularJS" group.
> > To unsubscribe from this group and stop receiving emails from it, send an
> > email to [email protected].
> > To post to this group, send email to [email protected].
> > Visit this group at http://groups.google.com/group/angular.
> > For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google Groups
> "AngularJS" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/angular.
> For more options, visit https://groups.google.com/d/optout.
>
--
You received this message because you are subscribed to the Google Groups
"AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.