diff options
author | Manuel Carrasco <manolo@apache.org> | 2013-12-03 00:54:27 -0800 |
---|---|---|
committer | Manuel Carrasco <manolo@apache.org> | 2013-12-03 00:54:27 -0800 |
commit | 9ba912bbd61be504da96749f6615a0db2518d9d1 (patch) | |
tree | 0fdaaf0a1d5c07cded1fe4f51a8f6bd39da19829 | |
parent | fc06a88c4e70fe444b1487646166fc430a2a2b0b (diff) | |
parent | fcdc407c7eca342b07c85123d1c5a82441f47550 (diff) | |
download | gwtquery-9ba912bbd61be504da96749f6615a0db2518d9d1.tar.gz gwtquery-9ba912bbd61be504da96749f6615a0db2518d9d1.zip |
Merge pull request #243 from manolo/mcm_cache_promises
Adding ability to cache promises.
2 files changed, 106 insertions, 20 deletions
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/FunctionDeferred.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/FunctionDeferred.java index 3b40fdce..771749f8 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/FunctionDeferred.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/FunctionDeferred.java @@ -21,29 +21,36 @@ import com.google.gwt.query.client.Promise.Deferred; * execution in pipelined processes. * * They have access to the associated deferred object via a method which - * will be called only in the case the previous promise is resolved + * will be called only in the case the previous promise is resolved. + * + * We can reuse the function and it will create new promises or will return + * the last one depending on the value of cache. It is very useful for caching + * server calls which we just want execute once like login, etc. * * <pre> - * Promise doSomething = new PromiseFunction() { + * Function login = new FunctionDeferred() { * @Override * public void f(Deferred dfd) { - * dfd.notify("hi"); - * dfd.resolve("done"); + * dfd.resolve("logged in as james-bond at " + new Date()); * } - * }; - * - * doSomething.then(new FunctionDeferred() { - * public void f(Deferred dfd) { - * dfd.resolve("deferred " + arguments(0)); + * }.withCache(RESOLVED); + * + * when(login) + * .then(new Function() { + * public void f() { + * String loginMessage = arguments(0); * } * }); * </pre> */ public abstract class FunctionDeferred extends Function { - + + public static enum CacheType {NONE, ALL, RESOLVED, REJECTED}; + protected Deferred dfd; public Function resolve, reject; - + private CacheType cache = CacheType.NONE; + /** * This function is called once the the previous promise in the * pipe is resolved, and the new created deferred is available. @@ -51,20 +58,46 @@ public abstract class FunctionDeferred extends Function { * You have to override it, and resolve the new promise */ protected abstract void f(Deferred dfd); - + /** * This function is called when the previous promise in the pipe * is resolved. */ public final Object f(Object... args) { - return new PromiseFunction() { - public void f(Deferred dfd) { - FunctionDeferred.this.resolve = resolve; - FunctionDeferred.this.reject = reject; - FunctionDeferred.this.dfd = dfd; - FunctionDeferred.this.f(dfd); - } - }; + return dfd != null && + (cache == CacheType.ALL || + cache == CacheType.RESOLVED && dfd.promise().isResolved() || + cache == CacheType.REJECTED && dfd.promise().isRejected()) + ? dfd.promise() + : new PromiseFunction() { + public void f(Deferred dfd) { + FunctionDeferred.this.resolve = resolve; + FunctionDeferred.this.reject = reject; + FunctionDeferred.this.dfd = dfd; + FunctionDeferred.this.f(dfd); + } + }; } + /** + * Configure whether cache the promise the first time it is resolved + * or create new promises each time the function is executed. + * + * By default cache is disabled. + */ + public FunctionDeferred withCache(CacheType type) { + cache = type; + return this; + } + + /** + * Reset the cache so as a new invocation to this function will + * execute it instead of restoring old values from cache. + */ + public FunctionDeferred resetCache() { + if (dfd != null && !dfd.promise().isPending()) { + dfd = null; + } + return this; + } } diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/deferred/DeferredTest.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/deferred/DeferredTest.java index 45eb6064..096e31bd 100644 --- a/gwtquery-core/src/test/java/com/google/gwt/query/client/deferred/DeferredTest.java +++ b/gwtquery-core/src/test/java/com/google/gwt/query/client/deferred/DeferredTest.java @@ -24,6 +24,7 @@ import com.google.gwt.query.client.GQuery; import com.google.gwt.query.client.Promise.Deferred; import com.google.gwt.query.client.plugins.deferred.Callbacks; import com.google.gwt.query.client.plugins.deferred.Callbacks.Callback; +import com.google.gwt.query.client.plugins.deferred.FunctionDeferred.CacheType; import com.google.gwt.query.client.plugins.deferred.FunctionDeferred; import com.google.gwt.query.client.plugins.deferred.PromiseFunction; @@ -371,4 +372,56 @@ public class DeferredTest extends GWTTestCase { }); } + private Boolean deferredData; + + public void testFunctionDeferredCache() { + + FunctionDeferred cachedFunction = new FunctionDeferred() { + protected void f(Deferred dfd) { + dfd.resolve(deferredData); + } + }; + + Function setDeferredDataToTrue = new Function(){ + public void f() { + deferredData = true; + } + }; + + Function setDeferredDataToFalse = new Function() { + public void f() { + deferredData = false; + } + }; + + Function assertDeferredDataIsFalse = new Function() { + public void f() { + Boolean data = arguments(0); + assertFalse(data); + } + }; + + Function assertDeferredDataIsTrue = new Function() { + public void f() { + Boolean data = arguments(0); + assertTrue(data); + } + }; + + when(setDeferredDataToTrue, cachedFunction.withCache(CacheType.ALL)) + .always(setDeferredDataToFalse) + .done(assertDeferredDataIsTrue) + .then(cachedFunction) + .done(assertDeferredDataIsTrue) + .then(cachedFunction.withCache(CacheType.REJECTED)) + .done(assertDeferredDataIsFalse) + .always(setDeferredDataToTrue) + .then(cachedFunction.withCache(CacheType.RESOLVED)) + .done(assertDeferredDataIsFalse) + .then(cachedFunction.resetCache()) + .done(assertDeferredDataIsTrue) + .then(cachedFunction) + .done(assertDeferredDataIsTrue) + ; + } } |