AngularJS学习之$q和promise介绍

引用:

​下面我们通过讲解$q的API让你更多的了解promise异步编程模式。$q是做为angularjs的一个服务而存在的,只是对promise异步编程模式的一个简化实现版,源码中剔除注释实现代码也就二百多行,下面开始介绍$q的API。

defer对象(延迟对象)可以通$q.defer()获取,下面是defer对象的api:

方法:

resolve(value):向promise对象异步执行体发送消息告诉他我已经成功完成任务,value即为发送的消息。

reject(value):向promise对象异步执行体发送消息告诉他我已经不可能完成这个任务了,value即为发送的消息。

notify(value):向promise对象异步执行体发送消息告诉他我现在任务完成的情况,value即为发送的消息。

  这些消息发送完promise会调用现有的回调函数。

属性:

promise即与这个defer对象的承诺对象。

  从上可以看出defer主要是用来发送消息的。

  promise对象可以通过defer.promise获取,下面是promise对象的api:

  then(successCallback,errorCallback,notifyCallback):参数为不同消息下的不同回调函数,defer发送不同的消息执行不同的回调函数,消息作为这些回调函数的参数传递。返回值为回一个promise对象为支持链式调用而存在。当第一个defer对象发送消息后,后面的promise对应的defer对象也会发送消息,但是发送的消息不一样,不管第一个defer对象发送的是reject还是resolve,第二个及其以后的都是发送的resolve,消息是可传递的。

  catch(errorCallback):then(null,errorCallback)的缩写。

  finally(callback):相当于then(callback,callback)的缩写,这个finally中的方法不接受参数,却可以将defer发送的消息和消息类型成功传递到下一个then中。

  defer():用来生成一个延迟对象 var defer =$q.defer();

  reject():参数接收错误消息,相当于在回调函数中抛出一个异常,然后在下一个then中调用错误的回调函数。

 all():参数接收为一个promise数组,返回一个新的单一promise对象,当这些promise对象对应defer对象全部解决这个单一promise对象才会解决,当这些promise对象中有一个被reject了,这个单一promise同样的被reject了。

 when():接收第一个参数为一个任意值或者是一个promise对象,其他3个同promise的then方法,返回值为一个promise对象。第一个参数若不是promise对象则直接运行success回调且消息为这个对象,若为promise那么返回的promise其实就是对这个promise类型的参数的一个包装而已,被传入的这个promise对应的defer发送的消息,会被我们when函数返回的promise对象所接收到。


代码示例:
/**  * 上传文件  * @param formData 附带参数  * @param success 成功回调 function  * @param error 失败回调 function  * @param progress 上传进度 function  */ hyHttp.upload = function(formData){
    var deferred = $q.defer();

    var url = encodeURI(this._url);
    var xhr = new window.XMLHttpRequest();
    if(xhr == null){
        throw new Error('您的浏览器不支持AJAX上传,请选择其他方式!');
    }
    xhr.onload = function(){
        if(xhr.readyState == 4){
            if(xhr.status == 200){
                deferred.resolve(xhr);
            }
        }
    };

    xhr.onerror = function(){
        deferred.reject(xhr);
    };

    xhr.upload.onprogress = function(event){
        if (event.lengthComputable) {
            deferred.notify(event);
        }
    };

    xhr.open('POST',url,true);
    xhr.setRequestHeader("","");
    xhr.send(formData);

    var promise = deferred.promise;
    promise.success = function(fn) {
        promise.then(function(response) {
            fn(response);
        });
        return promise;
    };
    promise.error = function(fn) {
        promise.then(null,function(response) {
            fn(response);
        });
        return promise;
    };
    promise.progress = function(fn) {
        promise.then(null,null,function(response) {
            fn(response);
        });
        return promise;
    };

    return promise;
};

相关文章

ANGULAR.JS:NG-SELECTANDNG-OPTIONSPS:其实看英文文档比看中...
AngularJS中使用Chart.js制折线图与饼图实例  Chart.js 是...
IE浏览器兼容性后续前言 继续尝试解决IE浏览器兼容性问题,...
Angular实现下拉菜单多选写这篇文章时,引用文章地址如下:h...
在AngularJS应用中集成科大讯飞语音输入功能前言 根据项目...
Angular数据更新不及时问题探讨前言 在修复控制角标正确变...