ES6(promise)_解决回调地狱初体验

一、前言                                                                                             

 

通过这个例子对promise解决回调地狱问题有一个初步理解。

 

二、主要内容                                                                                      

1回调地狱:如下图所示,一个回调函数里面嵌套一个回调函数,这样的代码可读性较低也比较恶心

 

 

2、下面用一个简单的例子来体验回调

      举例:我们想要按照顺序读取三个文件,a.txt  b.txt  c.txt  通过已经学的知识,发现下面的代码是不行的(代码是在node环境中实现)

      (1)项目目录结构如下:

      

 

    (2)callback.js: 如下  

var fs = require('fs');
//读取文件a.txt
fs.readFile('./data/a.txt', function (err, data) {
    if (err) {
        throw err
    }

    console.log(data.toString());
})

//读取文件b.txt
fs.readFile('./data/b.txt', function (err, data) {
    if (err) {
        throw err
    }

    console.log(data.toString());
})

//读取文件c.txt
fs.readFile('./data/c.txt', function (err, data) {
    if (err) {
        throw err
    }

    console.log(data.toString());
})

   (3)测试:发现读取文件的顺序并不是先a.txt --> b.txt -->c.txt,因为这里读取文件是异步的,这里执行的顺序取决于文件的大小

  

 

 

    (4)为了让读取的文件按照顺序来,我们可以用一下嵌套的方式 ,这种方式可以保证读取的顺序是按照a b c顺序来的,,但是代码嵌套得比较恶心,,这里只有三层嵌套,

var fs = require('fs');
//读取a.txt
fs.readFile('./data/a.txt', function (err, data) {
    if (err) {
        throw err
    }

    console.log(data.toString());
//读取b.txt
    fs.readFile('./data/b.txt', function (err, data) {
    if (err) {
        throw err
    }

    console.log(data.toString());
//读取c.txt
        fs.readFile('./data/c.txt', function (err, data) {
            if (err) {
                throw err
            }

            console.log(data.toString());
        })

    
})
})

 

 3、使用promise来解决回调嵌套(不了解promise的可以参照阮一峰老师的es6文档)

 

var fs = require('fs')

//创建p1的promise容器
var p1 = new Promise(function (resolve, reject) { fs.readFile('./data/a.txt', 'utf8', function (err, data) { if (err) { reject(err) } else { resolve(data) } }) })
//创建p2的promise容器
var p2 = new Promise(function (resolve, reject) { fs.readFile('./data/b.txt', 'utf8', function (err, data) { if (err) { reject(err) } else { resolve(data) } }) })
//创建p3的promise容器
var p3 = new Promise(function (resolve, reject) { fs.readFile('./data/c.txt', 'utf8', function (err, data) { if (err) { reject(err) } else { resolve(data) } }) })
p1 .then(function (data) { console.log(data)
// 当 p1 读取成功的时候 // 当前函数中 return 的结果就可以在后面的 then 中 function 接收到 // 当你 return 123 后面就接收到 123 // return 'hello' 后面就接收到 'hello' // 没有 return 后面收到的就是 undefined // 真正有用的是:我们可以 return 一个 Promise 对象 // 当 return 一个 Promise 对象的时候,后续的 then 中的 方法的第一个参数会作为 p2 的 resolve // return p2 }, function (err) { console.log('读取文件失败了', err) }) .then(function (data) { console.log(data) return p3 }) .then(function (data) { console.log(data) console.log('end') })

 

 

 

 为什么可以那样做:

 

 4、将上面的方法封装

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/a.txt')
  .then(function (data) {
    console.log(data)
    return pReadFile('./data/b.txt')
  })
  .then(function (data) {
    console.log(data)
    return pReadFile('./data/c.txt')
  })
  .then(function (data) {
    console.log(data)
  })

 

三、总结                                                                                             

 参考:阮一峰:http://es6.ruanyifeng.com

posted @ 2019-03-20 22:36  mysunshine_SZZ  阅读(645)  评论(0编辑  收藏  举报