diff --git a/mithril.js b/mithril.js index d8a8f8b0..080c6052 100644 --- a/mithril.js +++ b/mithril.js @@ -1055,6 +1055,14 @@ var m = (function app(window, undefined) { return propify(promise.then(resolve, reject), initialValue); }; prop["catch"] = prop.then.bind(null, null); + prop["finally"] = function(callback){ + var _callback = function(value){return m.deferred().resolve(callback(value)).promise;}; + return prop.then(function(value) { + return propify(_callback(value).then(function() {return value;}), initialValue); + }, function(reason) { + return propify(_callback(reason).then(function() {throw new Error(reason);}), initialValue); + }); + }; return prop; } //Promiz.mithril.js | Zolmeister | MIT diff --git a/tests/mithril-tests.js b/tests/mithril-tests.js index d0fd3dad..36c50785 100644 --- a/tests/mithril-tests.js +++ b/tests/mithril-tests.js @@ -3915,6 +3915,35 @@ function testMithril(mock) { mock.XMLHttpRequest.$instances.pop().onreadystatechange() return prop().message === "error occurred" && error().message === "error occurred" }) + test(function() { + // Data returned by then() functions propagate to finally(). + var data = m.prop(""); + var prop = m.request({method: "GET", url: "test"}).then(function() {return "foo"})["finally"](data) + mock.XMLHttpRequest.$instances.pop().onreadystatechange() + return prop() === "foo" && data() === "foo" + }) + test(function() { + // Data returned by finally() functions do *not* propagate to next promise. + var data = m.prop(""); + var prop = m.request({method: "GET", url: "test"}).then(function() {return "foo"})["finally"](function() {return "bar"}).then(data) + mock.XMLHttpRequest.$instances.pop().onreadystatechange() + return prop() === "foo" && data() === "foo" + }) + test(function() { + // Errors thrown in finally() can be caught by next promise. + var error = m.prop("no error") + var prop = m.request({method: "GET", url: "test"}).then(function() {return "foo"})["finally"](function() {throw new Error("error occurred")})["catch"](error) + mock.XMLHttpRequest.$instances.pop().onreadystatechange() + return prop().message === "error occurred" && error().message === "error occurred" + }) + test(function() { + // Promise finally() method occurrs after catch(). + var error = m.prop("no error") + var lastly = function() { error("lastly") }; + var prop = m.request({method: "GET", url: "test", deserialize: function() {throw new Error("error occurred")}})["catch"](error)["finally"](lastly) + mock.XMLHttpRequest.$instances.pop().onreadystatechange() + return prop().message === "error occurred" && error() === "lastly" + }) test(function() { var error = m.prop("no error"), exception var prop = m.request({method: "GET", url: "test", deserialize: function() {throw new TypeError("error occurred")}}).then(null, error)