Last active
August 29, 2015 14:08
-
-
Save thehydroimpulse/46ce18966a07b105afd4 to your computer and use it in GitHub Desktop.
Revisions
-
thehydroimpulse revised this gist
Oct 27, 2014 . 1 changed file with 0 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -25,12 +25,6 @@ class Jobber.Cache if value is request return Promise.resolve(value) Promise.reject() getPhotos = () -> -
thehydroimpulse revised this gist
Oct 27, 2014 . 1 changed file with 10 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,10 @@ # A slightly more abstracted version now using a `Resource` concept. Resources build # on-top of a `Request` and `Cache` seeing as there's a common idiom being formed in the above # file. Resource will check the cache first, then do the request and propagate errors exactly # the same way. # # But, this is super short and clear and this fully works offline. getPhotos = () -> Jobber.Resource('http://flickr.com/api/photos/1').then (res) -> res.body.photos ) -
thehydroimpulse created this gist
Oct 27, 2014 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,103 @@ # Provide an interface for working with an offline cache # that makes it easy to create an offline experience. class Jobber.Cache @extend Jobber.EmitterMixin # An in-memory cache for simplistic case. This should be something on disk to ensure # the persistence quality one needs for an offline experience. # # @property _cache Array<CacheItem> @_cache: [] # Put a new item into the cache # # @param {Any} request # @param {Any} item # @chainable # @return Jobber.Cache @put: (request, item) -> @_cache[request] = item @_cache.push item this @matches: (request) -> for key, value of @_cache if value is request return Promise.resolve(value) Promise.reject() class CacheItem @_request: null, @_item: null constructor: (@_request, @_item) -> getPhotos = () -> return new Promise( (resolve, reject) -> cachedData = null # Try and fetch from the cache first. Jobber.Cache.matches('http://flickr.com/api/photos/1').then((item) -> cachedData = item # This is where we would do some DOM operations or something with the cached data. The consumers # could listen on a `cached` event and do some early work so the user can use the cached data **before** # the API calls are triggered. ).finally -> # The cache might have failed or succeeded, we don't care. We'll try and # retrive the most up-to-date version anyways. Jobber.Request.create('http://flickr.com/api/photos/1').exec().then( (res, req) -> # Update the cache with the up-to-date version if we ever get to this state in the app. Jobber.Cache.put req, res.body.photos resolve(res.body.photos); ).fail -> # Well, we failed to perform an HTTP request. We're probably in an offline state. jobberApp.offline(1); if cachedData? return resolve(cachedData) else return reject("No internet connectivity, failed to do work!") ) # Show a simple spinner # @global showSpinner = -> $('.spinner').show() Promise.resolve() # Hide the global spinner # @global hideSpinner = -> $('.spinner').hide() Promise.resolve() # Now we can **easily** fetch the photos effectively: showSpinner() .then(getPhotos) .then( (photos) -> # Do something with the photos. These can be cached photos or # up-to-date versions, we don't really care. photosEl = $ '.photos' containerEl = document.createElement 'div' for photo in photos el = document.createElement 'div' el.classLists.add 'photo' el.innerHTML = "<img src='#{photo.src}' alt='#{photo.alt}' />" # Append each photo element into a container div. This still isn't # touching the DOM and is used to minimize the amount of operations we perform on # the DOM. Instead of performing an `.append` for each photo, which is at least O(n) # (Not counting the DOM internals work) we now achieve O(1) which is much better. containerEl.append el # Add the container to the DOM. photosEl.append containerEl ).fail( (err) -> # Show a small error message to say we have failed. el = $('.js-errorMessage') el.innerHTML = err el.show() ).finally(hideSpinner)