es6-深刻理解promise

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

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

下面咱们建立一个promise容器ajax

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

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

下面咱们写一个输出,promise

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,当异步执行完后输出3bash

在此强调下: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。 那么咱们如何使用它呢?ui

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

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

下面咱们来讲下解决回调地狱问题:

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的链式调用 上图来描述下,spa

下面咱们封装一个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()
    }
}
复制代码
相关文章
相关标签/搜索