zoukankan      html  css  js  c++  java
  • Promise

    初步了解Promise

    参考链接:

    吕大豹 大白话讲解Promise(一)

    Promise/A+规范

    linkFly6/Promise

    jQuery中的异步操作管理

    $.ajax()对象

    说明:主要用于异步请求,提供了success等Deferred的语法糖。

    常用方法:

    1. success
    2. error
    3. complete(指无论success或者error都会执行的操作。)
    4. ...

    示例(偷懒,直接从项目代码中接下来了0_0,看个样子就好。)

    //complete
    {
        //...
        getEngageTimeData: function (){
            var _self = this;
            $.ajax({
                type:'POST',
                url:baseUrl + 'getShowDatetime',
                data:{},
                success: function (response){
                    var response = JSON.parse(response);
                    if(response.status == 0){
                        _self.renderEngageTime(response);
                    }
                },
                error:function(){},
                complete: function (msg){
                    console.log('总是会执行的方法', msg);
                }
            });
        }
    }
    
    //then
    {
        //...
        getEngageTimeData:function (){
            var _self = this;
            $.ajax({
                type:'POST',
                url:baseUrl + 'getShowDatetime',
                data:{}
            }).then(function (response){
                var response = JSON.parse(response);
                if(response.status == 0){
                    _self.renderEngageTime(response);
                }
            }, function (){
                console.log('发生错误');
            });
        }
    }
    

    $.ajax()方法返回的对象不含resolve、reject等方法。

    $.Deffered()对象

    说明:主要是对异步操作的管理,实现了Promise规范。

    常用的方法:

    1. done
    2. fail
    3. always
    4. then
    5. ...

    它的方法与ajax对象的方法的对应关系是:

    graph LR
    done-->success
    fail-->error
    always-->complete
    then-->function(done, fail)
    Deffered方法-->ajax方法返回的是受限的Deffered对象
    

    $.whenjQuery的全局方法

    说明:异步操作并行执行,然后执行回调。

    示例:

    function async1() {
        var defer = $.Derferred();
        setTimeout(function() {
            console.log(1);
            defer.resolve('1');//'1':参数表示异步操作返回的数据;
        }, 1000);
        return defer.promise();
    }
    function async2() {
        //...
    }
    function async3() {
        //...
    }
    $.when(async1(), async2(), async3()).then(function(data1, data2, data3) {
        console.log('执行完毕');
        console.log(data1, data2, data3);
    });
    

    ES6(也就是ES2015)中的Promise规范

    首先看图:
    image

    可以看出Promise为一个构造函数,包含all、race、reject、resolve这四个主要的方法。其中:

    all对应$.when,可以管理多个异步操作的并行执行,然后等最慢的那个异步操作执行完毕后,执行回调。

    var async1 = function() {
        var p = new Promise(function(resolve, reject) {
        
            //异步操作
            resolve(data);  //异步操作返回的data数据
        });
        return p;   //因为使用new构造器时,会立即开始执行异步操作,所以需要包装在async1函数中,通过调用该函数执行想要进行的异步操作。
    };
    
    //$.when
    $
    .when(async1(), async2())
    .then(function(data1, data2) {
        console.log('所有异步操作执行完毕');
        console.log(data1, data2);  //各个异步操作返回的data值作为回调函数的参数。
    });
    //Promise.all
    Promise
    .all([async1(), async2()])
    .then(function(data) {
        console.log('所有异步操作执行完毕');
        console.log(data);  //data数组:n个异步操作返回的data值组成的数组。
    });
    

    race也可以管理多个异步操作的并行执行,和all不同的是:race是等待最快的那个异步操作执行完毕后,执行回调

    var async1 = function() {
        var p = new Promise(function(resolve, reject) {
            setTimeout(function() {
                console.log('async1');
                resolve('1');
            }, 1000);
        });
        return p;
    };
    var async2 = function() {
        var p = new Promise(function(resolve, reject) {
            setTimeout(function() {
                console.log('async2');
                resolve('2');
            }, 2000);
        });
        return p;
    };
    var async3 = function() {
        var p = new Promise(function(resolve, reject) {
            setTimeout(function() {
                console.log('async3');
                resolve('3');
            }, 3000);
        });
        return p;
    };
    Promise
    .race([async1(), async2(), async3()])
    .then(function(data) {
        console.log('执行回调');
        console.log(data);
    });
    //输出顺序为:
    //async1
    //执行回调
    //1
    //async2
    //async3
    

    reject一般用来处理异步操作过程中报错的情况,通常和catch配合使用

    ps:catch方法和try{}catch(e){}中的catch类似,用来执行reject的回调或者捕获resolve回调执行过程的错误信息,并进行处理。

    //情形一
    var async1 = function() {
       var p = new Promise(function(resolve, reject){
    		setTimeout(function() {
    			console.log('123');
    			if(true) {
    				reject('出错误了');
    			}else {
    				resolve('1');
    			}
    		}, 1000);
       });
       return p;
    };
    async1()
    .then(function(data) {
    	console.log('执行结果', data);
    })
    
    //作为reject的回调执行
    .catch(function(msg) {
    	console.log('错误信息:', msg);
    });
    
    //输出信息
    //123
    //错误信息:出错误了
    
    //情形二
    var async2 = function() {
       var p = new Promise(function(resolve, reject){
    		setTimeout(function() {
    			console.log('123');
    			if(false) {
    				reject('出错误了');
    			}else {
    				resolve('2');
    			}
    		}, 2000);
       });
       return p;
    };
    async2()
    .then(function(data) {
        console.log('执行结果', data);
        console.log(zgatry);    //未定义变量
    })
    
    //捕获resolve的回调执行过程中发生的错误。
    .catch(function(msg) {
        console.log('错误信息:', msg);
    });
    
    //输出信息
    //123
    //执行结果2
    //错误信息:ReferenceError: zgatry is not defined at <anonymous>:16:17
    

    ps:执行回调的过程中的错误信息需要通过catch来捕获,否则error会冒泡到全局环境下。

    image

    resolve和$.Deferred().resolve方法用法类似。

    链式调用

    var async1 = function() {
       var p = new Promise(function(resolve, reject){
    		setTimeout(function() {
    			if(false) {
    				reject('1出错误了');
    			}else {
    				resolve('1');
    			}
    		}, 1000);
       });
       return p;
    };
    var async2 = function() {
       var p = new Promise(function(resolve, reject){
    		setTimeout(function() {
    			if(false) {
    				reject('2出错误了');
    			}else {
    				resolve('2');
    			}
    		}, 2000);
       });
       return p;
    };
    async1()
    .then(function(data1) {
    	console.log('第一步执行完毕data1:', data1);
    	//console.log(error1);
    	return async2();
    })
    .then(function(data2) {
    	console.log('第二步执行完了data2:', data2);
    	//console.log(error2);
    })
    .catch(function(reason) {
    	console.log('错误信息', reason);
    });
    

    执行结果:

    image

    如果取消error1和error2的注释,则执行结果如下:

    image

    说明:前面的异步操作发生错误(执行了reject回调或者resolve回调中发生未知错误)会直接跳过后面的所有操作,由catch捕获并处理错误信息。

    Promise回顾和补充

    1. Promise是对延迟(deferred)和异步(asynchronous )操作的管理,可以在Js的同步代码中为某个异步操作完成后,执行回调。通过Promise对象封装,可以实现异步代码的扁平化管理,看起来更加优雅,也更符合书写逻辑,提高代码的可读性。
    2. Promise对象有三种状态
      • pending:初始状态
      • fulfilled:成功的操作
      • rejected:失败的操作
    3. 术语补充
      • promise是一个包含了兼容promise规范then方法的对象或函数,
      • thenable 是一个包含了then方法的对象或函数。
      • value 是任何Javascript值。 (包括 undefined, thenable, promise等).
      • exception 是由throw表达式抛出来的值。
      • reason 是一个用于描述Promise被拒绝原因的值。
    4. 浏览器兼容性
      • 原生的Promise对象仅支持ES5的现代浏览器可以使用。
      • jQuery的$.Deferred对象是从jQuery1.5.0版本开始引入的。

    image

    持续补充。
    time:2016-12-13

  • 相关阅读:
    最终项目 XMessenger Servers
    Linux下patch的制作和应用
    谈移动互联网入口
    绑定服务后台播放音频的简单示例
    MOQL操作数(Operand) (三)
    浅析Hibernate映射(二)——关系映射(3)
    【Extjs优化二】 Form表单提交通用
    Delphi Dll(1)
    用Groovy思考 第三章 Groovy开发环境
    JUnit单元测试入门(三)--JUnit简单实例
  • 原文地址:https://www.cnblogs.com/foxNike/p/6374598.html
Copyright © 2011-2022 走看看