Last active
December 25, 2015 19:08
-
-
Save richthegeek/7025163 to your computer and use it in GitHub Desktop.
Allow lazy evaluation of a string, such that you can have asynchronous parts to an otherwise synchronous evaluation. For example, part of the object may need to be loaded from the database but you don't want the code to be written with callbacks.
This file contains 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 characters
Q = require 'q' | |
class DeferredObject | |
constructor: (data) -> | |
@data = data | |
for k, v of @data | |
@__defineGetter__ k, -> this.data[k] | |
defer: (key, getter) -> | |
@__defineGetter__ key, => | |
if @data[key] | |
return @data[key] | |
defer = Q.defer() | |
getter @data, (err, result) => | |
if err | |
return defer.resolve [err] | |
@data[key] = result | |
defer.resolve [null, result] | |
throw defer.promise | |
get: (key, callback) -> | |
@eval "this.#{key}", callback | |
eval: (str, callback) -> | |
try | |
callback null, eval str | |
catch err | |
err.then ?= -> callback err | |
err.then (arg) => | |
[err, result] = arg | |
if err | |
return callback err | |
@eval str, callback |
This file contains 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 characters
obj = new DeferredObject {foo: 42} | |
obj.defer 'thing', (data, callback) -> | |
setTimeout (() -> callback null, 'this is a thing'), 500 | |
obj.eval 'this.thing.length', () -> | |
console.log 'result', arguments |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If a key is already defined in the deferred object, the getter will never be called in a deferred manner.
To defer an existing key, first delete it.