es6-深入理解promise

先讲一下什么是回调地狱->callback hell,给大家看一张图片,回调地狱就是异步里面套了异步,下面的异步请求依赖于上一个异步请求的结果,必须嵌套进去,放在回调里面,就形成了回调地狱。为了解决这一问题,es6出现了一个api,就是promise.

promise其实就是一个构造函数,我们typeof promise ,就能得出一个"function",也可以把它理解为一个容器,这个容器中存放了一个异步任务。它有三种状态,Pending(进行中),resolved(已成功),rejected(已失败)。

下面我们创建一个promise容器

Promise容器一旦创建,就开始执行里面的代码

var fs = require('fs')
new Promise(function(){
    fs.readFile('./a.txt','utf8,function(err,data)'{
        if(err){
            //失败了,承诺容器中的任务失败了
            console.log(err)
        }else{
            //承认容器中的任务成功了
            console.log(data)
        }
        
    })
})
复制代码

下面我们写一个输出,

console.log(1)
new Promise(function(){
    console.log(2)
    fs.readFile('./a.txt','utf8,function(err,data)'{
        if(err){
            //失败了,承诺容器中的任务失败了
            console.log(err)
        }else{
            console.log(3)
            //承认容器中的任务成功了
            console.log(data)
        }
        
    })
})
console.log(4)
复制代码

输出的结果是什么? 1 2 4 3 为什么会输出这样的呢?js执行顺序不是从上到下么?下面我们简单分析下: 先输出1,紧接着遇到了new promise,立即执行,输出2,我们上边提到了promise里面的任务是一个异步,所以执行输出4,当异步执行完后输出3

在此强调下:promise本身不是异步,但是内部往往都是封装一个异步任务。

下面我们继续,上边提到了promise有成功和失败的状态,所以我们把上边new promise的代码改写下。

var p1=new Promise(function(resolve,reject){
    fs.readFile('./a.txt','utf8,function(err,data)'{
        if(err){
            //失败了,承诺容器中的任务失败了
            //把容器的Pending状态变为失败Rejected
            //调用reject就相当于调用了then方法的第二个参数函数
           reject(err)
        }else{
            //承认容器中的任务成功了
            //console.log(data)
            //把容器的Pending状态变为成功resoved
            //也就是说这里调用的resolve方法实际上就是then方法传递的那个function
            resolve(data)
        }
    })
})
复制代码

上面的代码描述了我们图中promise的概念,promise里面有一个异步任务,默认的状态pending成功了变成resoved,失败了变成rejected。 那么我们如何使用它呢?

//p1就是promise
//当p1成功了然后(then)做指定的操作
//then方法接收的function就是容器中的resovle函数
p1
    .then(function(data){
        console.log(data)
    },function(err){
        console.log('读取失败了',err)
    })
复制代码

以上是promise的基础语法, 我用图来表示下

下面我们来说下解决回调地狱问题:

p1
.then(function(data)){
    //当p1读取成功的时候,当前函数中return的结果就可以在后面的thenfunction接收到,
    //当你return 123后面就接收到123
    // return 'hello' 后面就接收到'hello'
    //没有return 后面收到的就是undefined
    //其实我们真正用到的是可以return 一个promise对象
    //当return 一个Promise对象的时候,后续的then中的方法的第一个参数会作为p2的resolve
   // return 123
   
   return p2
},function(err){
    console.log(err)
})
.then(function(data){
    console.log(data) //在此接收p2的返回值
})

var p2=new Promise(function()){
    fs.readFile('./a.txt','utf8,function(err,data)'{
        if(err){
            reject(err)
        }else{
            resolve(data)
        }
    })
})
复制代码

我们也可以多添加几个then去返回多个new Promise,这个就是then的链式调用 上图来描述下,

下面我们封装一个readFile,

var fs = require('fs')
function pReadFile(filePath) {
    return new Promise(function (resolve,reject) {
        fs.readFile(filePath,'utf8',function (err,data) {
            if(err){
                reject(err)
            }else{
                resolve(data)
            }
        }
    }
}
pReadFile('./data/test.txt')
    .then(function(data){
        console.log(data)
        return pReadFile('./data/a.txt')
    })
    .then(function(data){
        console.log(data)
        return pReadFile('./data/b.txt')
    })
    .then(function(data){
        console.log(data  
    })
复制代码

以上是一个简单完整的小例子。 现在我们封装一个promise的ajax方法。

function pGet(url,callback){
    return new Promise(function(resolve,reject){
        var xhr = new XMLHttpRequest()
        xhr.onload = function(){
            callback && callback(JSON.parse(pGet.responseText))
            resolve(JSON.parse(pGet.responseText))
        }
        xhr.onerror = function(){
            reject(err)
        }
        xhr.open("get",url,true)
        xhr.send()
    }
}
复制代码

转载于:https://juejin.im/post/5c0fad386fb9a049eb3bc7c0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值