Promise
一 介绍
1.什么是promise
我们知道JavaScript语言的执行环境是“单线程”,所谓单线程,就是一次只能够执行一个任务,如果有多个任务的话就要排队,前面一个任务完成后才可以继续下一个任务。
这种“单线程”的好处就是实现起来比较简单,容易操作;坏处就是容易造成阻塞,因为队列中如果有一个任务耗时比较长,那么后面的任务都无法快速执行,或导致页面卡在某个状态上,给用户的体验很差。
当然JavaScript提供了“异步模式”去解决上述的问题,关于“异步模式”JavaScript提供了一些实现的方法:回调函数(callbacks)、事件监听、Promise对象。callback是最最简单的机制,可是用这种机制的话必须牺牲控制流、异常处理和函数语义化为代价,甚至会让我们掉进出现callback大坑,而promise解决了这个问题。
2.Promise是一种异步方式处理值(或者非值)的方法,promise是对象,代表了一个函数最终可能的返回值或者抛出的异常。
在与远程对象打交道时,Promise会非常有用,可以把它们看作远程对象的一个代理。
优点:使
用了promise的收获之一是逃脱了回调的固定思维逻辑。promise让异步处理的机制看上去更像是同步,基于同步函数我们可以按照预期来捕获返回值
和异常值。可以在程序中的任何时刻捕捉错误,并且绕过依赖于程序异常的后续代码,我们不需要思考这个同步带来的好处。因此使用promise的目的是:获
取功能组合和错误冒泡能力的同时,保持代码异步运行的能力。
二 使用
1.想要在angularjs中创建promise,可以使用内置的$q服务,$q服务在它的deferred API中提供了一些方法。

们可以先使用$q的defer()方法创建一个deferred对象,然后通过deferred对象的promise属性,将这个对象变成一个
promise对象;这个deferred对象还提供了三个方法,分别是resolve(),reject(),notify()。
2.先了解一下任务的状态
每个任务都有三种状态:未完成(pending)、完成(fulfilled)、失败(rejected)。
pending状态:可以过渡到履行或拒绝状态。
fulfilled状态:不能变为其他任何状态,而且状态不能改变,必须有value值。
rejected状态:不能变为其他任何状态,而且状态不能改变,必须有reason。
3.deffered对象
(1)deffered 对象的方法
resolve(value):resolve函数用这个值来执行deferred promise,在声明resolve()处,表明promise对象由pending状态转变为resolve。
reject(reason):它等同于使用一个“拒绝”来执行一个promise,在声明resolve()处,表明promise对象由pending状态转变为rejected。
notify(value) :在声明notify()处,表明promise对象unfulfilled状态,在resolve或reject之前可以被多次调用。
(2)deffered 对象属性
promise :最后返回的是一个新的deferred对象 promise 属性,而不是原来的deferred对象。这个新的Promise对象只能观察原来Promise对象的状态,而无法修改deferred对象的内在状态可以防止任务状态被外部修改。
4.promise对象
promise对象的方法
(1)then(successFunc,
errorFunc,
notifyFunc):无论promise是成功了还是失败了,当结果可用之后,then都会立刻异步调用successFunc,或者
'errorFunc',在promise被执行或者拒绝之前,notifyFunc可能会被调用0到多次,以提供过程状态的提示。
(2)catch(errorCallback) —— promise.then(null, errorCallback) 的快捷方式
(3)finally(callback) ——让你可以观察到一个 promise 是被执行还是被拒绝, 但这样做不用修改最后的 value值。 这可以用来做一些释放资源或者清理无用对象的工作,不管promise 被拒绝还是解决。
5.举例
HTML部分:
<div ng-app="MyApp">
    <div ng-controller="MyController">
        <label for="flag">成功
        <input id="flag" type="checkbox" ng-model="flag" /><br/>
        </label>
        <hr/>
        <button ng-click="handle()">点击我</button>
    </div>
</div>
JS部分:
angular.module("MyApp", [])
.controller("MyController", ["$scope", "$q", function ($scope, $q) {
            $scope.flag = true;
            $scope.handle = function () {
            var deferred = $q.defer();  //创建deferred对象
            var promise = deferred.promise;   //创建promise对象

promise.then(function (result) {  //then方法传递两个处理函数
                alert("Success: " + result);  //promise被执行时进行
            }, function (error) {  //promise被拒绝时进行
                alert("Fail: " + error);
            });

if ($scope.flag) {
                deferred.resolve("you are lucky!");  //给promise传值
            } else {
                deferred.reject("sorry, it lost!");
            }
        }
}]);


果异步操作成功,则用resolve方法将Promise对象的状态变为“成功”(即从pending变为resolved);如果异步操作失败,则用
reject方法将状态变为“失败”(即从pending变为rejected)。最后返回 deferred.promise
,我们就可以链式调用then方法。
再来一个小例子:
var ngApp=angular.module('ngApp',[]);
ngApp.factory('UserInfoService',['$http','$q',function($http,$q){
    return{
       query:function(){
        var defer=$q.defer();  //声明延后执行
        $http({method:'GET',url:'data/students.json'}).
        success(function(data,status,headers,config){
            defer.resolve(data);  //声明执行成功
            console.log('UserInfoService success');
        }).
        error(function(data,status,headers,config){
            defer.reject();      //声明执行失败
        });
                         
        return defer.promise; //返回承诺,返回获取数据的API
        }
        }
    }]);
             
    ngApp.controller('MainCtrl',['$scope','UserInfoService',function($scope,UserInfoService){
         var promise = UserInfoService.query();  //同步调用,获取承诺接口
        promise.then(function(data){
            $scope.user=data;  //调用承诺接口resolove()
            console.log('MainCtrl ...');
            },function(data){
              $scope.user={error:'数据不存在。。。'}; //调用承诺接口reject();
            });
                 
            }]);
6.使用then进行链式请求

promiseB = promiseA.then(function(result) {  
      return result + 1;  
    });  
  // promiseB 将会在处理完 promiseA 之后立刻被处理,  
  // 并且其  value值是promiseA的结果增加1

angularJS promise $q的更多相关文章

  1. angularJS $http $q $promise

    一天早晨,爹对儿子说:“宝儿,出去看看天气如何!” 每个星期天的早晨,爹都叫小宝拿着超级望远镜去家附近最高的山头上看看天气走势如何,小宝说没问题,我们可以认为小宝在离开家的时候给了他爹一个promis ...

  2. AngularJS promise()

    实例说明一 <!DOCTYPE html> <html ng-app="my-app"> <head> <meta charset=&qu ...

  3. angularjs 缓存 $q

    <!DOCTYPE HTML> <html ng-app="myApp"> <head> <meta http-equiv="C ...

  4. Angularjs -Promise - $http

    https://www.peterbe.com/plog/promises-with-$http

  5. angularJS中的Promise对象($q)的深入理解

    原文链接:a better way to learn AngularJS - promises AngularJS通过内置的$q服务提供Promise编程模式.通过将异步函数注册到promise对象, ...

  6. AngularJS 承诺 Promise

    一.概念解释 全称是未来与承诺,Futures and promises,是一种编程模式,不是AngularJS首创.javascript里有个流行库Q,而AngularJS是$q,其就是从Q引入的: ...

  7. promise理解

    每个操作都返回一样的promise对象,保证链式操作 每个链式都通过then方法 每个操作内部允许犯错,出了错误,统一由catch error处理 操作内部,也可以是一个操作链,通过reject或re ...

  8. Node.js最新技术栈之Promise篇

    前言 大家好,我是桑世龙,github和cnodejs上的i5ting,目前在天津创业,公司目前使用技术主要是nodejs,算所谓的MEAN(mongodb + express + angular + ...

  9. promise、resolve、reject、拦截响应

    Promise是一个接口,它用来处理的对象具有这样的特点:在未来某一时刻(主要是异步调用)会从服务端返回或者被填充属性.其核心是,promise是一个带有then()函数的对象. 使用promise机 ...

随机推荐

  1. 使用AutoMapper实现Dto和Model之间自由转换

    应用场景:一个Web应用通过前端收集用户的输入成为Dto,然后将Dto转换成领域模型并持久化到数据库中.另一方面,当用户请求数据时,我们又需要做相反的工作:将从数据库中查询出来的领域模型以相反的方式转 ...

  2. Core Data 教学

    看了一篇国外的文章,关于iOS9的Core Data教学,在这里做了一下总结 Core Data 教学 示例开源地址:LastDayCoreData 在这篇文章中我们将学习Core Data的系列教程 ...

  3. 使用SQL Server 2008远程链接时SQL数据库不成功的解决方法

    关键设置: 第一步(SQL2005.SQL2008): 开始-->程序-->Microsoft SQL Server 2008(或2005)-->配置工具-->SQL Serv ...

  4. throw 导致 Error C2220, wraning C4702错误

    今天在程序加了一个语句,发现报 Error C2220, Wraning C4702错误 查询Wraning C4702 ,[无法访问的代码] 由于为 Visual Studio .NET 2003 ...

  5. 【vc】6_菜 单

    1.菜单命令响应函数: 提示:MFC都是采用大写字母来标识资源ID号的:为了区分资源类型,一般遵循这样一个原则:在“ID”字符串后加上一个标识资源类型的字母.例:菜单资源(Menu):ID_Mxxx: ...

  6. iOS 数据持久性存储-对象归档

    对象归档是将对象归档以文件的形式保存到磁盘中(也称为序列化,持久化),使用的时候读取该文件的保存路径读取文件的内容(也称为解档,反序列化) 主要涉及两个类:NSKeyedArichiver.NSKey ...

  7. C# 控制台程序设置字体颜色

    这几天做了个程序,程序本身很简单.大体功能是输入查询条件,从数据库里取出结果计算并显示.但是用户的要求是使用控制台(console)来实现功能.由于功能简单,程序很快就做完了,在面向用户演示程序时,突 ...

  8. 利用sfntly的sfnttool.jar提取中文字体

    雨忆博客中提到了sfntly(具体介绍可以看:https://code.google.com/p/sfntly/),利用其中sfnttool.jar就可以提取只包含指定字符的字体,如果想在页面中通过@ ...

  9. Android 常用系统控件

    1. 日期选择器 DatePickerDialog 2. 时间选择器 TimePickerDialog 3. 单选按钮 RadioButton 4. 多选按钮 CheckBox 5. 下拉列表 Spi ...

  10. C语言结构体(struct)使用方法

    基本定义:结构体,通俗讲就像是打包封装,把一些变量有共同特征(比如同属于某一类事物的属性)的变量封装在内部,通过一定方法访问修改内部变量. 结构体定义: 第一种:只有结构体定义 struct stuf ...