5.1 KiB
m.deferred
This is a low-level method in Mithril. It's a modified version of the Thenable API.
A deferred is an asynchrony monad. It exposes a promise property which can bind callbacks to build a computation tree.
The deferred object can then apply a value by calling either resolve or reject, which then dispatches the value to be processed to the computation tree.
Each computation function takes a value as a parameter and is expected to return another value, which in turns is forwarded along to the next computation function (or functions) in the tree.
Usage
//standalone usage
var greetAsync = function() {
var deferred = m.deferred();
setTimeout(function() {
deferred.resolve("hello");
}, 1000);
return deferred.promise;
};
greetAsync()
.then(function(value) {return value + " world"})
.then(function(value) {console.log(value)}); //logs "hello world" after 1 second
Differences from Promises/A+
For the most part, Mithril promises behave as you'd expect a Promise/A+ promise to behave, but with a few key differences:
Mithril promises forward a value downstream if a resolution callback returns undefined. This allows simpler debugging of promise chains:
var data = m.request({method: "GET", url: "/data"})
.then(console.log) //Mithril promises let us debug like this
.then(doStuff)
var data = m.request({method: "GET", url: "/data"})
.then(function(value) { // Promises/A+ would require us to declare an anonymous function
console.log(value) // here's the debugging snippet
return value // and we need to remember to return the value as well
})
.then(doStuff) // or else `doStuff` will break
Another subtle difference is that the Promises/A+ require a callback to run in a different execution context than its respective then method. This requirement exists to support an obscure edge cases and incurs a significant performance hit on each link of a promise chain. To be more specific, the performance hit can come either in the form of a 4ms minimum delay (if the implementation uses setTimeout), or from having to load a bunch of hacky polyfill code for a feature that is not being considered for addition by some browser vendors.
To illustrate the difference between Mithril and A+ promises, consider the code below:
var deferred = m.deferred()
deferred.promise.then(function() {
console.log(1)
})
deferred.resolve("value")
console.log(2)
In the example above, A+ promises are required to log 2 before logging 1, whereas Mithril logs 1 before 2. Typically resolve/reject are called asynchronously after the then method is called, so normally this difference does not matter.
Signature
Deferred deferred()
where:
Deferred :: Object { Promise promise, void resolve(any value), void reject(any value) }
Promise :: GetterSetter { Promise then(any successCallback(any value), any errorCallback(any value)) }
GetterSetter :: any getterSetter([any value])
-
GetterSetter { Promise then([any successCallback(any value) [, any errorCallback(any value)]]) } promise
A promise has a method called
thenwhich takes two computation callbacks as parameters.The
thenmethod returns another promise whose computations (if any) receive their inputs from the parent promise's computation.A promise is also a getter-setter (see
m.prop). After a call to eitherresolveorreject, it holds the result of the parent's computation (or theresolve/rejectvalue, if the promise has no parent promises)-
Promise then([any successCallback(any value) [, any errorCallback(any value)]])
This method accepts two callbacks which process a value passed to the
resolveandrejectmethods, respectively, and pass the processed value to the returned promise-
any successCallback(any value) (optional)
The
successCallbackis called ifresolveis called in the rootdeferred.The default value (if this parameter is falsy) is the identity function
function(value) {return value}If this function returns undefined, then it passes the
valueargument to the next step in the thennable queue, if any -
any errorCallback(any value) (optional)
The
errorCallbackis called ifrejectis called in the rootdeferred.The default value (if this parameter is falsy) is the identity function
function(value) {return value}If this function returns undefined, then it passes the
valueargument to the next step in the thennable queue, if any -
returns Promise promise
-
-
-
void resolve(any value)
This method passes a value to the
successCallbackof the deferred object's child promise -
void reject(any value)
This method passes a value to the
errorCallbackof the deferred object's child promise