zoukankan      html  css  js  c++  java
  • 浅谈Promise语法API+封装

    为了解决回调地狱callback fell嵌套带来的问题,ES6新增了一个API:Promise(译为承诺保证),本质为“构造函数”

    注意:Promise是ES6新增的方法,与node无关,在浏览器端也可以执行

    (1)分析

      Promise可以理解为一个容器,容器里放了一个异步任务,默认异步任务分为3种状态

    1、pending译为(在...期间),表示正在进行的状态,默认便是pending正在执行状态。例如读取文件,默认为正在读... ...
      接下来pending只能变成两种状态:“完成”or“失败”
    2、resolved译为(成功、已解决),表示任务成功
    3、rejected译为(失败、驳回、拒绝),表示任务失败

      注意:状态是不可逆的.

      

    (2)Promise代码编写

      1、新建文件demo-promise.js,用来编写执行promise相关API

        首先明确一点,Promise是ES6新语法,不是node独有的,浏览器亦可执行,如下所示

        

         返回构造函数,接下来看下如何使用。

      2、创建Promise容器

            

      3、容器中一般放置异步任务,里面传一个函数作为参数

        

       4、Promise不是异步,但Promise承诺容器里的任务一定是异步的,验证如下

        

        执行结果如下

        

    由此可知Promise承诺不是异步的,因为2在1后面,在4前面。而Promise承诺容器里的任务是异步的

        注意:

        

      5、接下来pending状态要转变成“resolved成功”或者“rejected失败”状态

        首先传入形参resolve和reject

         然后改变状态

         接下来将Promise容器实例绑定到变量,建立引用关系

        

      6、变量实例调用then方法

        

         做个简单验证

        

        分析:也就是说这里调用的resolve方法实际上就是then方法传递的那个function

        

         接下来传入data即可获取读取文件成功后返回的结果

      7、then方法第二个参数函数

    调用reject就相当于调用了then方法的第二个参数函数

        

         接下来可以做个简答验证,修改文件路径为错误路径

        

         

    目前为止只关注Promise语法部分,还没有涉及解决回调地狱问题

        语法解析:

    1、通过new Promise创建承诺容器,在内部执行异步操作,传入参数resolve和reject。成功时调用resolve(data),pending进行中状态更改为成功。失败调用reject(error),
      传入错误对象,状态更改为失败;
    2、如何获取成功或失败的数据呢??? 方法:通过Promise实例对象的then方法,接收两个参数函数,第一个为成功函数参数对应之前的resolve(data),第二个为失败函数对应之前的reject(error)

      8、完整代码的图例分析

        

        

    (3)解决嵌套问题

      1、接下来再新建两个Promise实例

        

        

      2、二次then方法

        

    接下来再次调用then方法,接收第一个then成功函数返回值,验证如下

        

         

         如果第一个then参数函数,没有return返回值,则返回undefined,接着修改

        

    注意:
        当这里return一个Promise即p2时,后续的then中方法的第一个参数会作为p2的resolve成功函数,验证如下

        

         接着读取p3,如下所示

        

    这里便是then方法的链式调用,验证如下

        

         总代码如下:

        

         代码结构图:

        

      3、缺点

    目前为止可以通过promise实例的then方法链式调用解决回调嵌套问题。但仍有不足,如下所示:代码重复率较高,封装性不好,
    所以接下来封装Promise,即new Promise创建承诺容器可以进一步封装

        

    (4)总结

    最后,对比代码如下

    回调地狱方法:

    var fs = require('fs')
    
    fs.readFile('./a.txt','utf8',function(error,data){
        if(error){
            /*return console.log('读取失败')*/
            /*另外,也可以手动抛出异常,阻止程序执行且返回错误信息到控制台*/
            throw error
        }
        console.log(data)
        fs.readFile('./b.txt','utf8',function(error,data){
            if(error){
                /*return console.log('读取失败')*/
                /*另外,也可以手动抛出异常,阻止程序执行且返回错误信息到控制台*/
                throw error
            }
            console.log(data)
            fs.readFile('./c.txt','utf8',function(error,data){
                if(error){
                    /*return console.log('读取失败')*/
                    /*另外,也可以手动抛出异常,阻止程序执行且返回错误信息到控制台*/
                    throw error
                }
                console.log(data)
            })
        })
    })

    Promise方法:

    var fs = require('fs')
    
    var p1 = new Promise(function(resolve,reject){
        fs.readFile('./a.txt','utf8',function(error,data){
            if(error){
                reject(error)
            }else{
                resolve(data)
            }
        })
    })
    var p2 = new Promise(function(resolve,reject){
        fs.readFile('./b.txt','utf8',function(error,data){
            if(error){
                reject(error)
            }else{
                resolve(data)
            }
        })
    })
    var p3 = new Promise(function(resolve,reject){
        fs.readFile('./c.txt','utf8',function(error,data){
            if(error){
                reject(error)
            }else{
                resolve(data)
            }
        })
    })
    /*读取*/
    p1
        .then(function(data){
            console.log(data)
            return p2
        },function(error){
            console.log('读取a文件失败'+error)
        })
        .then(function(data){
            console.log(data)
            return p3
        },function(error){
            console.log('读取b文件失败'+error)
        })
        .then(function(data){
            console.log(data)
        },function(error){
            console.log('读取c文件失败'+error)
        })

    结果:

    (5)封装Promise版本的readFile

    var fs = require('fs')
    
    function promiseReadFile(filePath){
        return new Promise(function(resolve,reject){
            fs.readFile(filePath,'utf8',function(error,data){
                if(error){
                    reject(error)
                }else{
                    resolve(data)
                }
            })
        })
    }
    
    promiseReadFile('./a.txt')
        .then(function(data){
            console.log(data)
            return promiseReadFile('./b.txt')
        })
        .then(function(data){
            console.log(data)
            return promiseReadFile('./c.txt')
        })
        .then(function(data){
            console.log(data)
        })

    .

  • 相关阅读:
    [c++]基类对象作为函数參数(赋值兼容规则)
    easyui datagird 总计栏
    openssl之BIO系列之25---结束语
    具体解释Hibernate中的二级缓存
    记真实自己,炫精彩人生---《爱记》app使用体验
    设置-安全-手机加密功能解说
    Linux下Redis安装
    解题报告 之 HDU5317 RGCDQ
    FireFox所支持的全部标签(持续更新ing)
    本书已出版<拨云见日:基于android的内核与系统架构源代码分析 >
  • 原文地址:https://www.cnblogs.com/fightjianxian/p/12266432.html
Copyright © 2011-2022 走看看