- ۹۶/۰۱/۰۳
- ۰ دیدگاه
Promises
In order to properly use asynchronous operations in your Angular code, use promises. Prior to introduction of promises, people used callback functions.
* Promises are provided by $q service.
* Instantiating a promise is basically telling JS to "wait for this to finish".
* You wrap logic inside the promise, with calls to resolve()
instead of return
.
* Where your normal function would return a final value, the async method returns a promise of having the value in the future.
* As promise.then()
and promise.catch()
return promises, they can be chained in an operation called composition. Composition refers to the execution of several async calls in parallel and getting the result, once all the promises have been resolved.
Promise States
* Pending: an initial state, not fulfilled or rejected
* Fulfilled: the operation completed successfully
* Rejected: the operation failed
* Settled: the operation is either fulfilled or rejected, but not pending
* Resolved: the promise is settled or locked into a promising chain
Using Promises
Declaring Promises
angular.module('myApp', [])
myApp.service('myService', ['$q', function($q){
}])
Then there are two ways to declare your promise, $q.when()
or $q.defer()
. These methods serve different purposes, $q.when()
can turn any value-based function into a promise, whose return value can then be used. It is primarily useful for situations where a 3rd party promise (such as jQuery's), is being used in a library. $q.defer()
- on the other hand - declares a standalone promise that will resolve with whatever data you pass to it through $q.resolve
or $q.reject
.
//These are the two methods of declaring promises.
//For all intents and purposes these declarations
//are the same, other than the reasons listed above.
//$q.defer() method
function demonstrateDefer(){
var deferred = $q.defer()
$http.get('someresource').then(function(response){
$q.resolve(response)
})
return $q.promise()
}
//$q.when() method
function someOtherFunction(){
return $http.get('someresource')
}
$q.when(someOtherFunction()).then(function(){
})
Promise Return Value
To use a promises return value, you make use of the .then()
method on the promise object.
It can either only do something on success:
httpResponseFunction().then(function(response){
doStuffWithReponse(response)
})
Or it can have an additional function passed to it to handle failures:
httpResponseFunction().then(function(response){
doStuffWithResponse(response)
}, function(error){
handleErrors(error)
})
Chaining and Combining Promises
Chaining promises is one of the most powerful features of $q
. Simply put, a return value from a then()
statement passes to the next then()
statement in the promise.
function deferThis(){
var deferred = $q.defer()
$http.get('something').then(function(response){
deffered.resolve(response)
})
return deferred.promise
}
function passTheBuck(response){
deferThis.then(function(response){
doStuffWithResponse(response)
})
}
Rejecting promises can happen at any point in the chain cleanly, causing each error callback below where it was called to be fired.
function deferThis(){
//If the failure occurs within this promise, errorhandle1() will be called
var deferred = $q.defer()
$http.get('something').then(function(response){
deffered.resolve(response)
}, function(error){
errorHandle1(error)
})
return deferred.promise
}
function passTheBuck(){
//If the failure occurs here, errorhandle1() and errorhandle2() will be called,
//but not errorhandle3()
var deferred2 = $q.defer()
deferThis.then(function(response){
deferred2.resolve(response)
}, function(error){
errorHandle2(error)
})
return deferred2.promise
}
function passMoreBucks(){
//If the failure occurs here,
//errorhandle1(), errorhandle2(), and errorhandle3() will all be called
passTheBuck.then(function(response){
console.log(response)
}, function(error){
errorhandle3(error)
})
}
Combining promises makes use of the .all()
method.
function deferThis(){
var deferred = $q.defer()
$http.get('something').then(function(response){
deffered.resolve(response)
}, function(error){
errorHandle1(error)
})
return deferred.promise
}
function deferAnother(){
var deferred = $q.defer()
$http.get('something').then(function(response){
deffered.resolve(response)
}, function(error){
errorHandle1(error)
})
return deferred.promise
}
$q.all(deferThis(), deferAnother()).then(function(response){
promiseOneReturnFunction(response[0])
promiseTwoReturnFunction(response[1])
})
AJAX Calls in Angular
$http
The $http
service is a function that takes a single argument (a configuration object) that generates an HTTP request and returns a promise. This promise will be resolved to a response object when the request succeeds or fails. The configuration object is the object describing the request to be made and how it should be processed.
The response object has these properties:
* Data
: {string|Object}, The response body transformed with the transform function
* Status
: {number}, HTTP status code of the response
* Headers
: {function([headerName])}, Header getter function
* Config
: {Object}, The configuration object that was used to generate the request
* StatusText
: {string}, HTTP status text of the response
You can use $http
like this:
var req = {
method: 'POST',
url: 'http://example.com',
headers: {
'Content-Type': undefined
},
data: { test: 'test' }
}
$http(req).then(function(){...}, function(){...});
Check out $http
documentation for more information on other parameters you can use in configuration object.
Also, there are some shortcuts for common cases:
$http.get
$http.post
$http.head
$http.put
$http.delete
$resource
This service allows you to create convenient methods for dealing with RESTful APIs.
Declare it like this:
var resource = $resource(url, [paramDefaults], [actions], options);
For example:
$resource('http://example.com/resource/:resource_id.:format')
Week One Week Two Week Three Week Four Week Five