diff options
author | Manuel Carrasco Moñino <manuel.carrasco.m@gmail.com> | 2013-11-30 12:57:24 +0100 |
---|---|---|
committer | Manuel Carrasco Moñino <manuel.carrasco.m@gmail.com> | 2013-11-30 12:57:24 +0100 |
commit | f7119204c7717ec7f396079df182f111f7f35b2b (patch) | |
tree | ae0d7d460f8b30376184039b5a3143630b1aa075 | |
parent | 9df2f18c2b655db88abc31787ae7903f01f71060 (diff) | |
download | gwtquery-f7119204c7717ec7f396079df182f111f7f35b2b.tar.gz gwtquery-f7119204c7717ec7f396079df182f111f7f35b2b.zip |
Adding ability to cache promises.
2 files changed, 96 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..9c7f16ef 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,46 @@ 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) + ; + } } |