回调地狱与Promise解决回调地狱的问题

和异步编程有关

无法保证顺序的代码

var fs=require('fs');

fs.readFile('./data/a.txt','utf8',function(err,data){
    if(err){
        // return console.log('读取失败')
        //抛出异常
        //1,阻止程序的执行
        //2,把错误消息打印到控制台
        throw err
    }
    console.log(data)
})

fs.readFile('./data/b.txt','utf8',function(err,data){
    if(err){
        // return console.log('读取失败')
        //抛出异常
        //1,阻止程序的执行
        //2,把错误消息打印到控制台
        throw err
    }
    console.log(data)
})

fs.readFile('./data/c.txt','utf8',function(err,data){
    if(err){
        // return console.log('读取失败')
        //抛出异常
        //1,阻止程序的执行
        //2,把错误消息打印到控制台
        throw err
    }
    console.log(data)
})

​
通过回调嵌套的方式保证顺序
​
var fs=require('fs')

fs.readFile('./data/a.txt','utf8',function(err,data){
    if(err){
        // return console.log('读取失败')
        //抛出异常
        //1,阻止程序的执行
        //2,把错误消息打印到控制台
        throw err
    }
    console.log(data)
    fs.readFile('./data/b.txt','utf8',function(err,data){
        if(err){
        // return console.log('读取失败')
        //抛出异常
        //1,阻止程序的执行
        //2,把错误消息打印到控制台
        throw err           
        }
        console.log(data)
        fs.readFile('./data/c.txt', 'utf8', function (err, data) {
            if (err) {
              // return console.log('读取失败')
              // 抛出异常
              //    1. 阻止程序的执行
              //    2. 把错误消息打印到控制台
              throw err
            }
            console.log(data)
        })
    })
})

为了解决以上编码方式带来的问题(回调地狱嵌套),所以在ES6中新增了一个API:Promise

Promise基本语法

var fs = require('fs')
//在ES6中新增了一个API Promise//Promise 是一个构造函数
//创建Promise 容器,Promise本身不是异步,但是里面的任务是异步的//1,给别人一个承诺(异步任务)//   Promise 容器一旦创建,就开始执行里面的代码var p1 = new Promise(function (resolve, reject) {
  fs.readFile('./data/a.txt', 'utf8', function (err, data) {
    if (err) {
        //把容器的Pending状态变为Rejected
        //实际上就是then方法传递的那个function(err)
      reject(err)
    } else {
        //把容器的Pending状态变为Resolved
        //也就是说这里调用的resolve方法实际上就是then方法传递的那个function(data)
      resolve(data)
    }
  })
})
//p1就是那个承诺//当p1成功了,然后(then)做指定的操作//then方法接收的function就是容器中的resolve函数
p1
  .then(function(data){
    console.log(data)
  },function(err){
      console.log('读取文件失败了',err)
  })

解决回调地狱问题

var fs = require('fs')
var p1 = new Promise(function (resolve, reject) {
  fs.readFile('./data/a.txt', 'utf8', function (err, data) {
    if (err) {
      reject(err)
    } else {
      resolve(data)
    }
  })
})
var p2 = new Promise(function (resolve, reject) {
  fs.readFile('./data/b.txt', 'utf8', function (err, data) {
    if (err) {
      reject(err)
    } else {
      resolve(data)
    }
  })
})
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')
  })

封装Promise版本的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/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)
  })

猜你喜欢

转载自blog.csdn.net/qq_40885461/article/details/88667547