Promise
we need to know some extra knowledge before we talk about it. We know that the JavaScript implementation environment is "single-threaded", so-called single-threaded, is only able to perform one task at a time, if there are multiple tasks to queue, the previous task is completed before the next task can continue.
This "single-threaded" advantage is simple to implement, easy to operate, the disadvantage is that it is prone to blocking, because if a task in the queue time is longer, then the subsequent tasks can not be executed quickly, or cause the page card in a state, the user experience is poor.
Of course, JavaScript provides an "asynchronous pattern" to solve the above problems, and the "Asynchronous Pattern" JavaScript provides some implementation methods.
- callback function (callbacks)
- Event Monitoring
- Promise Object
As for the callback function, everyone should be familiar with the following code (note: Refer to a little code above Leancloud):
Av. User.login ("MyName", "Mypass", { function(user) { // do stuff after Successful login. }, function (user, error) { // the login failed. Check error to see why. } });
Users through the user name and password to log in, if the successful landing, will be in success
this module processing, if the login failed, will be in error
this module processing.
When we need to deal with the task is not a lot of cases, the use of the callback function is still manageable, there is not much problem, but when we need to deal with more tasks, the use of the callback function is more and more obvious, first, the callback makes the call inconsistent, not guaranteed, when dependent on other callbacks, The process of tampering with the code, which is difficult to debug, requires an explicit processing error after each call, and finally, too many callbacks make the code less readable and maintainable, so more programmers choose to use it Promise
to handle asynchronous patterns.
Promise
we will explain in detail below.
Promise
What is it
Promise
is an asynchronous way of handling a value (or a non-value), promise
an object that represents the final possible return value of a function or an exception thrown.
When dealing with remote objects, it Promise
can be useful to think of them as a proxy for a remote object.
Click on the link below to view Promise
more information
Use
Promise
The reasons
- Using
Promise
can let us escape callback to hell, so that our code looks like synchronization.
- You can catch errors anywhere in your program, and bypass subsequent code that relies on program exceptions to get the ability to combine functionality and error bubbling, and most importantly, to keep the ability to run asynchronously.
- The readability and maintainability of our code are made very good.
How the
AngularJS
Used in
Promise
The AngularJS
Promise
built-in service to use in AngularJS
$q
.
$q
The service is inspired by the Kris Kowal Library, so it is Q
similar to that library, but does not contain the functionality used by that library.
$q
is AngularJS
integrated with the $rootScope
template, so AngularJS
both execution and rejection are quick.
$q promise
is AngularJS
integrated with the template engine, which means that any found in the view Promise
will be executed or rejected in the view.
We can first use $q
the defer()
method to create an deferred
object, and then through deferred
the object's promise
properties, the object into an promise
object, this deferred
object also provides three methods, namely resolve()
, reject()
, notify()
.
Let's step through the code to implement the above functions, after all, say more, than you actually knock them into code to achieve.
Test1
Let's start with a synchronous example to create an promise
object.
HTML code:
<div ng-app= "MyApp" > <div ng-controller= "Mycontroller" > for = "Flag" > success <input id= "flag" type= "checkbox" ng-model= "Flag"/><br/> </label>
JS Code:
Angular.module ("MyApp", []). Controller ("Mycontroller", ["$scope", "$q",function($scope, $q) {$scope. Flag=true; $scope. Handle=function () { varDeferred =$q. Defer (); varPromise =deferred.promise; Promise.then (function(Result) {alert ("Success:" +result); }, function(Error) {alert ("Fail:" +error); }); if($scope. Flag) {Deferred.resolve ("You are lucky!"); } Else{deferred.reject ("Sorry, it lost!"); } }}]);
Let us analyze the above code in detail, we html
have added one on the page checkbox
, one button
purpose is to checkbox
click on checkbox
the button below to bring up different content when we select and uncheck.
var deferred = $q.defer()
This code creates an deferred
object, and we then var promise = deferred.promise
create an object by using it promise
.
The method we give promise
is then
passed two processing functions, dealing with the actions to be performed when it promise
is executed and when it promise
is rejected.
The following if(){}else{}
block of statements contains execution and rejection deferred promise
, if $scope.flag
true
Yes, then we will execute deferred promise
, and then we promise
pass a value, or it may be an object that indicates promise
the result of the execution. If it $scope.flag
is false
, then we will reject deferred promise
, and then we promise
pass a value, or it may be an object that indicates promise
the reason for being rejected.
Now looking back, promise
the then
method, if promise
executed, then the first function in its argument result
represents the"you are lucky!"
We are using synchronous mode for the time being, in order to be able to illustrate the problem, we will use the Async method later.
Here we can see how $q
the defer()
method created by the object has
resolve(value)
: Used to execute deferred promise
, value
can be a string, object, etc.
reject(value)
: Used to reject deferred promise
, value
can be a string, object, etc.
notify(value)
: Gets deferred promise
the execution state, and then uses this function to pass it.
then(successFunc, errorFunc, notifyFunc)
: Whether it promise
succeeds or fails, when the result is available, it is then
immediately called asynchronously successFunc
, or ' Errorfunc ', and promise
may be called 0 to several times before being executed or rejected notifyFunc
to provide a hint of the process state.
catch(errorFunc)
finally(callback)
Online Code Part1
By using
then
Making chained requests
We use then
methods to make chained calls, and the benefit is that no matter whether the previous task or then
function is executed or rejected, it does not affect the then
operation of the subsequent function.
We can do then
this by creating an execution chain that allows us to interrupt the application process based on more versatility, which can lead to different results, which allows us to pause the execution of the delay at any point in the execution chain promise
.
Test2
HTML code
<div ng-app= "MyApp" > <div ng-controller= "Mycontroller" > for = "Flag" > success <input id= "flag" type= "checkbox" ng-model= "Flag"/><br/> </label> <div Ng-cloak > {status} }</div>
JS Code:
Angular.module ("MyApp", []). Controller ("Mycontroller", ["$scope", "$q",function($scope, $q) {$scope. Flag=true; $scope. Handle=function () { varDeferred =$q. Defer (); varPromise =deferred.promise; Promise.then (function(Result) {result= result + "You are passed the first then ()"; $scope. Status=result; returnresult; }, function(Error) {Error= Error + "Failed but we have passed the first and then ()"; $scope. Status=error; returnerror; }). Then (function(Result) {alert ("Success:" +result); }, function(Error) {alert ("Fail:" +error); }) if($scope. Flag) {Deferred.resolve ("You are lucky!"); } Else{deferred.reject ("Sorry, it lost!"); } }}]);
Online Code Part2
We added some code based on the PART1 code and promise
added a new handler function to the original chain to then()
create an execution connection to see how it was executed on this execution connection promise
.
One thing to note is that in the first then()
method, we changed the value in the first successFunc
function, and the result
value in the second errorFunc
function error
changed.
Because this promise
object runs through the entire execution chain, then()
changing its value in the first method must be reflected in the following then()
method
An instance of an asynchronous Pattern Test3In the third example, we create a service and then create one in this service promise
, the purpose of which is to pull the data from the github
above angularjs
pull
, and the detailed code can look at the following
The following example contains a bit more, because I made the changes in the previous example, and you can just look at promise
this part.
Directory structure:
- MyApp
- Js
- App.js
- Controller.js
- Service.js
- Views
- Index.html
Js/app.js
Angular.module ("MyApp", ["Ngroute", "Mycontroller", "MyService"]). config ([function($ Routeprovider) { $routeProvider . When ('/', { "views/home.html", " Indexcontroller " });}]);
Js/controller.js
Angular.module ("Mycontroller", []). Controller ("Indexcontroller", ["$scope", "Githubservice",function($scope, Githubservice) {$scope. Name= "Dreamapple"; $scope. Show=true; Githubservice.getpullrequests (). Then (function(Result) {$scope. Data=result; },function(Error) {$scope. Data= "error!"; },function(Progress) {$scope. Progress=progress; $scope. Show=false; }); }]);
Js/service.js
Angular.module ("MyService", []). Factory (' Githubservice ', ["$q", "$http",function($q, $http) {varGetpullrequests =function(){ varDeferred =$q. Defer (); varPromise =deferred.promise; varprogress; $http. Get ("Https://api.github.com/repos/angular/angular.js/pulls"). Success (function(data) {varresult = []; for(vari = 0; i < data.length; i++) {Result.push (data[i].user); Progress= (i+1)/data.length * 100;deferred.notify (progress); } deferred.resolve (Result); }). Error (function(Error) {Deferred.reject (error); }); returnpromise; } return{getpullrequests:getpullrequests};}]);
Views/home.html
Index.html
<!--do not put the following comments out of the problem, I mean upload to Segmentfault--><!--
http://segmentfault.com/a/1190000002788733
Give you a promise-play turn AngularJS Promise (Turn)