浅谈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)
    })

 

 

 

 

.

posted @ 2020-02-05 20:38  剑仙6  阅读(358)  评论(0编辑  收藏  举报
欢迎访问个人网站www.qingchun.在线