• Promise用法总结


    1. Promise的状态
     
    Promise对象有三个状态:
    1. 进行中(pending)
    2. 成功(resolved)
    3. 失败(rejected)
     
    2. 生成一个Promise对象
     
    1. 构造函数
    new Promise(function(resolve,reject){
     
    });
    resolve和reject函数是浏览器内部实现的,直接调用即可。
     
    2. Promise.resolve
    Promise.resolve()直接返回一个resolve状态的Promise对象
    Promise.resolve可以用来生成一个then链
     
    3. Promise.reject
    Promise.reject()直接返回一个reject状态的Promise对象
     
    3. Promise的then的用法

    Promise的then永远返回一个新的Promise,Promise的catch是then(null,rejection)的语法糖,catch中也会返回一个新的Promise。
    建议在Promise的then永远return或throw,不要只是执行一个函数。

    例如:
    var aPromise = new Promise(function (resolve) {
        resolve(100);
    });
    var thenPromise = aPromise.then(function (value) {
        console.log(value);
    });
    var catchPromise = thenPromise.catch(function (error) {
        console.error(error);
    });
    console.log(aPromise !== thenPromise); // => true
    console.log(thenPromise !== catchPromise);// => true
    === 是严格相等比较运算符,我们可以看出这三个对象都是互不相同的,这也就证明了 then 和 catch 都返回了和调用者不同的promise对象。

    1. Promise的then内部可以做三种事情:
     
    (1). return 另一个promise
    (2). return 一个同步值(或者undefined)
    因为javascript函数无返回值时候,默认返回undefined,所以只是执行一个函数,不return,默认就是返回undefined。
    返回一个同步值在Promise中会将同步代码包裹为promise,得到的还是一个promsie。返回一个同步值是有用处的,例如,
    一个异步值在内存中做了缓存,可以直接从内存中拿到该值,直接返回,不必再调用异步接口。
    getUserByName('xxx').then(function(user){
        if(imMemoryCache[user.id]){
            return inMemoryCache[user.id];
        }
        return getUserAccountById(user.id);
    }).then(function(userAccount){
    
    });
    (3). throw 一个同步异常
     
    2. Promise的一些写法
    new Promise(function(resolve,reject){
        resolve(syncValue);
    }).then(/*...*/)
    
    //可以写成
    Promise.resolve(syncValue).then(/*...*/)
    
    //一个错误也可以写成
    Promise.reject(new Error('...'))
    这样无论成功或失败都可以后面的then和catch中捕获和继续操作
     
    3. Promise的then中只能传递函数,如果为其他类型,例如另一Promise,会被解释为null,此时Promsie的值传递会穿透
     
    例如:
    Promise.resolve('foo').then(Promise.resolve('bar')).then(function(result){
        console.log(result);
    });
    //会被解释为:
    Promise.resolve('foo').then(null).then(function(result){
        console.log(result);
    });
    第一个resolve的值会穿透到then,打印出foo。
     
    4. then的四种写法的区别
    // 写法一
    f1().then(function () {
        return f2();
    });
    
    // 写法二
    f1().then(function () {
        f2();
    });
    
    // 写法三
    f1().then(f2());
    
    // 写法四
    f1().then(f2);
    1. 写法1和4完全等价,f1值能传递到f2,f2的返回值也能继续向后面的then传递
    2. 写法2相当于默认return undefined,无法向后面的then传递值
    3. 写法3能够向后面传递f2的值,没有更深刻的解释(有懂的朋友请评论告知)

    4. Promise的调用方法

    每个then返回一个新的promise调用,这种写法被称为composing promises。
    promise1.then(function(){
        return promise2;
    }).then(function(){
        return promise3;
    }).then(function(){
        return promise4;
    }).catch(function(err){
        console.log(err);
    });
    5. Promise的并行执行

    由于promise一旦被创建,就会立即执行,所以拿到一个Promise数组时候,其中的promise必然全部开始执行了。
    因此要让一系列promise顺序执行,只能将promise放在一个函数中,在要执行的时候才去创建他,就是一个工厂
    函数,promiseFactory。promise并行执行的代码应该如下:
    function executeSequentially(promiseFactories){
        var res = Promsie.resolve();
        promiseFactories.forEach(function(promiseFactory){
            res = res.then(promiseFactory);
        });
        return res;
    }
    //工厂函数只是简单的创建一个promise
    function promiseFactory(){
        return createAPromise();
    }
    6. Promise捕获错误
    7. 实现一个Promise版本的ajax
    //原生版本
    function Http(){
    
    }
    
    Http.prototype = {
        get:function(opts){
            return this.ajax(opts);
        },
        post:function(){
            return this.ajax(opts);
        },
        ajax:function(opts){
            return Promise(function(resolve,reject){
                var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('...');
                var {url,method,data,async,success,fail} = options;
                var sendBody = null;
                var qs = Object.keys(data).reduce(function(cur,pre,index){
                    return pre + '&' + encodeURIComponent(cur) + '=' + encodeURIComponent(data[cur]);
                },'').slice(1);
                if(medthod == 'get'){
                    url += '?' + qs;
                }
                else if(medhot == 'post'){
                    xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
                    sendBody = qs || null;
                }
                xhr.onreadystatechange = function(){
                    if(xhr.readystate == 4){
                        if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
                            resolve(xhr,xhr.responseText);
                        }
                    }
                    else{
                        reject(xhr,xhr.responseText);
                    }
                }
                xhr.open(method,url,async);
                xhr.send(sendBody);
            });
        }
    }
    
    //jquery版本
    function Http(){
    
    }
    
    Http.prototype = {
        get:function(opts){
            return this.ajax(opts);
        },
        post:function(opts){
            return this.ajax(opts);
        },
        ajax:function(){
            return $.ajax(opts);
        }
    }
    参考:https://juejin.im/entry/596f2ab2f265da6c25190f41
         http://javascript.ruanyifeng.com/advanced/promise.html#toc2
       https://www.kancloud.cn/kancloud/promises-book/44256
  • 相关阅读:
    Viewpager的用法
    Android上下文菜单
    Android开机自启动程序
    微信小程序踩过的坑
    Sublime Text 配置python文件
    Pandas速查手册中文版
    scrapy架构设计分析
    爬虫服务集群处理nginx返回504
    phantomjs 无法打开https网站
    Selenium判断获取的元素是否可见(display:none)
  • 原文地址:https://www.cnblogs.com/mengff/p/9646392.html
Copyright © 2020-2023  润新知