I have an object (foo
) that exposes several methods as promises (using JQuery deferred). The way I did it ended up with this kind of code:
var foo = createNewFoo();
$.when(foo.method1(arg))
.then(foo.method2)
.then(foo.method3);
I wish to refactor my code to something nicer, like this:
var foo = createNewFoo()
.method1(arg)
.method2()
.method3();
But I'm not sure how to implement foo
so it would be possible.
Yes sure, you just need to extend your
Deferred
s to have these methods:Of course, with a real promise library all this is a lot easier than with jQuery's minimal promises.
This would let you do:
I'm not sure it's worth it, but it works.
You will need to return a custom object with the methods you need, and let it have a promise for the state instead of the state as properties directly. In every of your methods, you'd need to call
then
on the wrapped promise, and return another instance that wraps a new promise for the new state (method result).This is similar to the approaches outlined by Benjamin Gruenbaum and Louy, but with a much simpler implementation.
I'm not really aware of Promises (so forgive my example if there is some implementation error) but this is possible using ES6
Proxy
.At this time it's only available on the latest browsers so it might not meet your requirements.
A Proxy allow to add a callback function on each object operations, it mean that you can retrieve the name of the called method to do what you want. In your case you want to call
$.when()
with the first promise and call.then()
with others as parameter.Assuming you're using a "class" defined as bellow
You can now use this piece of code to chain your promises
And retrieve the original Foo instance
Create your own promise.
Add whatever methods you want...
voila!
Bonus:
Also in ES6: