As pointed out in the comments, look at the $q implementation in AngularJS. Documents are notorious for being ... sometimes hard to understand.
But anyway, try a short example. I do this in CoffeeScript because I prefer it, but you should compile the coffeescript.org example if you want.
Let me implement the service:
app = angular.module 'my.custom.services', ['your.other.modules'] app.factory 'Service', ['$http' , '$q', (http, q) ->
It is easy. Itโs just a service that will use $q and $http , because: a) we want to get some of these sweet promises that we are talking about, and b) "$ http" is a good example in itself for what you can call asynchronous, and the result of which is not immediately available.
The interesting part here is the get part of the object, which returns here. Note that the service is implemented as a factory , not as a service . For differences see here . I usually think of it as a โfancyโ version for a service, where I just have extra space for my own logic before exposing the service API (it really means something else, but it's for a different story.
In either case, get will return the promise deferred object when called. promise is an object that provides the then method. When using this service, you are likely to enter it like this:
app = angular.module 'my.custom.application', ['my.custom.services'] app.controller 'AppController', ['Service', (service)-> service.get()
As I said, get will simply return a promise. Promises, like in real life, should be allowed somewhere. So let's do it in the service - our promise will be fulfilled when we finish the task that we promised. It could be something like calling a URL via AJAX or a big computation (does anyone know what the 117th Fibonacci number is?).
In our example, we use the http call, as it is now, regardless of whether we return or not, and even when it returns to us:
app.factory 'Service', ['$http' , '$q', (http, q) ->
Based on someCondition , we can resolve the request if we want. If you want to try it yourself, you can also use timeout , as in the docs.
What is happening now? Well, we still have this controller around:
app.controller 'AppController', ['Service', (service)-> service.get().then(successCallback, errCallback) ]
As I explained, promise provides a then method with a signature then(success, error) , where success and error are functions that take everything that we have allowed as arguments, for example:
app.controller 'AppController', ['Service', (service)-> successCallback = (data) ->
If you want to pass multiple values โโto callbacks, I would suggest you pass the object when you allow / refuse a promise. You can also make callback calls to promise, for example angular makes an $http implementation in it:
app.factory 'Service', ['$http' , '$q', (http, q) ->
You significantly extend the promise given back by the success method, which takes one method as a callback, expects the promise to be resolved, and then uses the callback. You can do the same for any other method if you want (for tips see the angular implementation )
In your controller, you can use it as follows:
service.get().success (arg1, arg2, arg3) -> # => arg1 is data.payload, arg2 is data.status, arg3 is the additional object service.get().error (err) -> # => err
These are the basics, you can experiment, if you want, I suggest you try the following:
- Multiple promises in a service with multiple pending promises
- Try another method of deferring the result, for example, a long calculation
And, as a bonus:
- Try isolating success / error callbacks in named service methods
This example uses the implementation of $q in Angular, you can, of course, use another implementation for Promises, for example this , which is the basis for $q .