From 0e1b3ac267eaccd1b0de3d13586f367f3c953752 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Manuel=20Carrasco=20Mo=C3=B1ino?= Date: Mon, 18 Mar 2013 17:18:42 +0100 Subject: [PATCH] Re-write Promise.then since it must return a new promise instead of itself --- .../com/google/gwt/query/client/Promise.java | 9 ++- .../gwt/query/client/plugins/ajax/Ajax.java | 69 +++++++++---------- .../client/plugins/deferred/Callbacks.java | 4 ++ .../client/plugins/deferred/Deferred.java | 26 ++++--- .../gwt/query/client/GQueryAjaxTestGwt.java | 23 ++++++- .../query/client/GQueryDeferredTestGwt.java | 22 +++++- 6 files changed, 105 insertions(+), 48 deletions(-) diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Promise.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Promise.java index 03c7327b..3785b9c3 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/Promise.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/Promise.java @@ -87,8 +87,13 @@ public interface Promise { String state(); /** - * Add handlers to be called when the Deferred object is resolved, rejected, or still in progress. - * + * Add filters to be called when the Deferred object is resolved, rejected, or still in progress. + * + * These handlers are used to eventually change the values used to resolve the promise. + * + * `then` returns a new Promise which will be resolved with the values returned by the handlers + * in old jquery versions `then` was called `pipe`. + * * @param f a list of 1, 2, or 3 functions, which will be used in this way: * 1st function will be called when the deferred is resolved. * 2nd function that is called when the deferred is rejected. diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ajax/Ajax.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ajax/Ajax.java index fefcb67f..6f094d5e 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ajax/Ajax.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ajax/Ajax.java @@ -2,6 +2,7 @@ package com.google.gwt.query.client.plugins.ajax; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Element; +import com.google.gwt.http.client.Request; import com.google.gwt.http.client.RequestBuilder; import com.google.gwt.http.client.RequestBuilder.Method; import com.google.gwt.http.client.Response; @@ -13,8 +14,8 @@ import com.google.gwt.query.client.builders.JsonBuilder; import com.google.gwt.query.client.js.JsUtils; import com.google.gwt.query.client.plugins.Plugin; import com.google.gwt.query.client.plugins.deferred.Deferred; -import com.google.gwt.query.client.plugins.deferred.PromiseReqBuilderJSONP; import com.google.gwt.query.client.plugins.deferred.PromiseReqBuilder; +import com.google.gwt.query.client.plugins.deferred.PromiseReqBuilderJSONP; import com.google.gwt.user.client.ui.FormPanel; /** @@ -110,13 +111,11 @@ public class Ajax extends GQuery { final Function onSuccess = settings.getSuccess(); if (onSuccess != null) { onSuccess.setElement(settings.getContext()); - dfd.promise().done(onSuccess); } final Function onError = settings.getError(); if (onError != null) { onError.setElement(settings.getContext()); - dfd.promise().fail(onError); } Method httpMethod = resolveHttpMethod(settings); @@ -125,41 +124,39 @@ public class Ajax extends GQuery { final String dataType = settings.getDataType(); if ("jsonp".equalsIgnoreCase(dataType)) { - int timeout = settings.getTimeout(); - return getJSONP(url, onSuccess, onError, timeout); - } - - createPromiseRequestBuilder(settings, httpMethod, url, data) - .done(new Function() { - public void f() { - Response response = arguments(0); - Response request = arguments(1); - Object retData = null; - try { - if ("xml".equalsIgnoreCase(dataType)) { - retData = JsUtils.parseXML(response.getText()); - } else if ("json".equalsIgnoreCase(dataType)) { - retData = JsUtils.parseJSON(response.getText()); - } else { - retData = response.getText(); - } - } catch (Exception e) { - if (GWT.getUncaughtExceptionHandler() != null) { - GWT.getUncaughtExceptionHandler().onUncaughtException(e); + return getJSONP(url, onSuccess, onError, settings.getTimeout()); + } else { + return createPromiseRequestBuilder(settings, httpMethod, url, data) + .then(new Function() { + public Object f(Object...args) { + Response response = (Response)args[0]; + Request request = (Request)args[1]; + Object retData = null; + try { + if ("xml".equalsIgnoreCase(dataType)) { + retData = JsUtils.parseXML(response.getText()); + } else if ("json".equalsIgnoreCase(dataType)) { + retData = JsUtils.parseJSON(response.getText()); + } else { + retData = response.getText(); + } + } catch (Exception e) { + if (GWT.getUncaughtExceptionHandler() != null) { + GWT.getUncaughtExceptionHandler().onUncaughtException(e); + } } + return new Object[]{retData, "success", request, response}; } - dfd.resolve(retData, "success", request, response); - } - }) - .fail(new Function() { - public void f() { - Throwable exception = arguments(0); - Response request = arguments(1); - dfd.reject(null, exception.getMessage(), request, null, exception); - } - }); - - return dfd.promise(); + }, new Function() { + public Object f(Object...args) { + Throwable exception = (Throwable)args[0]; + Response request = (Response)args[1]; + return new Object[]{null, exception.getMessage(), request, null, exception}; + } + }) + .done(onSuccess) + .fail(onError); + } } private static Promise createPromiseRequestBuilder(Settings settings, Method httpMethod, String url, String data) { diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/Callbacks.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/Callbacks.java index 5471ed29..a81c92e7 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/Callbacks.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/Callbacks.java @@ -175,6 +175,10 @@ public class Callbacks { @SuppressWarnings({"unchecked", "rawtypes"}) private boolean run(Object c, Object...o) { + // Unbox array into array, it happens when running filters in Promise.then + if (o.length == 1 && o[0].getClass().isArray()) { + o = (Object[])o[0]; + } if (c instanceof Callback) { return ((Callback)c).f(o); } else if (c instanceof Function) { diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/Deferred.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/Deferred.java index 027d230b..b086773e 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/Deferred.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/deferred/Deferred.java @@ -68,14 +68,24 @@ public class Deferred extends GQuery implements Promise.Deferred { return dfd.state; } - public Promise then(Function... f) { - assert f.length < 4 : "Promise.then: Too much arguments"; - switch (f.length) { - case 3: progress(f[2]); - case 2: fail(f[1]); - case 1: done(f[0]); - } - return this; + public Promise then(final Function... f) { + final Deferred newDfd = new com.google.gwt.query.client.plugins.deferred.Deferred(); + progress(new Function() { + public void f() { + newDfd.notify(f.length > 2 ? f[2].f(getArguments()) : getArguments()); + } + }); + fail(new Function() { + public void f() { + newDfd.reject(f.length > 1 ? f[1].f(getArguments()) : getArguments()); + } + }); + done(new Function() { + public void f() { + newDfd.resolve(f.length > 0 ? f[0].f(getArguments()) : getArguments()); + } + }); + return newDfd.promise(); } public boolean isResolved() { diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTestGwt.java index c257971b..292d74c6 100644 --- a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTestGwt.java +++ b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTestGwt.java @@ -271,7 +271,7 @@ public class GQueryAjaxTestGwt extends GWTTestCase { }, 500); } - public void testJsonTimeout() { + public void testJsonpTimeout() { delayTestFinish(5000); String nonJsonpUrl = "http://127.0.0.1/nopage"; @@ -292,5 +292,26 @@ public class GQueryAjaxTestGwt extends GWTTestCase { Ajax.ajax(s); } + + public void testAjaxError() { + delayTestFinish(5000); + String url = "http://127.0.0.1/nopage"; + + Ajax.ajax(Ajax.createSettings().setTimeout(1000).setUrl(url)) + .done(new Function(){ + public void f() { + fail(); + } + }).fail(new Function(){ + public void f() { + System.out.println(arguments(0)); + System.out.println(arguments(1)); + System.out.println(arguments(2)); + System.out.println(arguments(3)); + System.out.println(arguments(4)); + finishTest(); + } + }); + } } diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java index 8c011a24..d5cbcb77 100644 --- a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java +++ b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java @@ -19,8 +19,8 @@ package com.google.gwt.query.client; import com.google.gwt.junit.client.GWTTestCase; import com.google.gwt.query.client.plugins.ajax.Ajax; import com.google.gwt.query.client.plugins.deferred.Callbacks; -import com.google.gwt.query.client.plugins.deferred.PromiseFunction; import com.google.gwt.query.client.plugins.deferred.Callbacks.Callback; +import com.google.gwt.query.client.plugins.deferred.PromiseFunction; import com.google.gwt.user.client.Timer; /** @@ -258,4 +258,24 @@ public class GQueryDeferredTestGwt extends GWTTestCase { }); } + public void testWhen() { + new PromiseFunction() { + public void f(final Deferred dfd) { + dfd.resolve(5); + } + }.done(new Function() { + public void f() { + assertEquals(5d, arguments(0)); + } + }).then(new Function() { + public Object f(Object... args) { + return (Double)args[0] * 2; + } + }).done(new Function() { + public void f() { + assertEquals(10d, arguments(0)); + } + }); + } + } -- 2.39.5