使用node内置模块util结合promise实现文件的异步读写

回调地狱问题

首先,回调地狱并不是错误,没有语法错误。但是层层嵌套,代码不优雅

如何解决呢?
优化的方向就是 把异步的代码 外观上同步化

Promise关键字 承诺许诺

promise初体验

/* 
  首先,回调地狱并不是错误,没有语法错误。但是层层嵌套,代码不优雅

  如何解决呢?
    优化的方向就是 把异步的代码 外观上同步化

    Promise关键字 承诺许诺

*/

const path = require('path')
const fs = require('fs')
const fil1 = path.join(__dirname, './test/a.txt')
const fil2 = path.join(__dirname, './test/b.txt')
const fil3 = path.join(__dirname, './test/c.txt')

fs.readFile(
  fil1, 'utf-8', (error, data1) => {
    if (error) {
      return console.log(error.message);
    }
    // 读取成功
    fs.readFile(
      fil2, 'utf-8', (error2, data2) => {
        if (error) {
          return console.log(error2.message);
        }
        fs.readFile(
          fil3, 'utf-8', (error3, data3) => {
            if (error) {
              return console.log(error3.message);
            }
            // 输出读取到的数据
            // console.log('读取成功!');
            // console.log(data1 + data2 + data3);
          }
        )
      }
    )
  }
)

// console.log('================================');

// 使用promise对象解决回调地狱问题
// 1. 创建 Promise对象
// 箭头函数里面两个形参,两个形参是两个函数,
// 成功执行第一个函数,失败执行第二个
// new Promise( (resolve,reject)=>{} )
let p1 = new Promise((resolve, reject) => {
  // 同步的代码放在这里,但是一般不会放同步的代码

  fs.readFile(fil1, 'utf-8', (error, data) => {
    if (error) {
      // 读取失败。执行reject函数
      return reject(error)
    }
    // 读取成功 执行resolve函数
    resolve(data)
  })
})

// 书写回调函数
// new Promise().then(成功后执行的函数,失败后执行的函数)
p1.then(
  (data) => {
    // 打印读取成功后的数据
    console.log(data);
  },
  (error) => {
    // 读取失败,打印错误信息
    console.log(error.message);
  }
)

promise的then方法的链式书写

// new Promise().then() 的链式调用
const path = require('path')
const fs = require('fs')
const fil1 = path.join(__dirname, './test/a.txt')
const fil2 = path.join(__dirname, './test/b.txt')
const fil3 = path.join(__dirname, './test/c.txt')


let p1 = new Promise((resolve, reject) => {
  // 同步的代码放在这里,但是一般不会放同步的代码

  fs.readFile(fil1, 'utf-8', (error, data) => {
    if (error) {
      // 读取失败。执行reject函数
      return reject(error)
    }
    // 读取成功 执行resolve函数
    resolve(data)
  })
})

// then的链式调用,第一个then函数执行后,无论成功与否,都会执行后续的then函数
// then函数里面的两个函数参数,都可以有返回值,返回值会被下一个then里面的函数形参接收
// 如果返回值是promise对象,下一个then里面函数的形参接收的不是这个promise对象,而是这个promise对象内部的调用resolve函数的参数或者reject函数的参数

p1.then(
  (data) => {
    // 打印读取成功后的数据
    console.log(data);
    // return '读取成功'
    return p1
  },
  (error) => {
    // 读取失败,打印错误信息
    console.log(error.message);
  }
).then((data) => {
  console.log(data);
  console.log('我是第二个then');
}, () => {

})

使用promise完成多文件读写操作

// new Promise().then() 的链式调用
const path = require('path')
const fs = require('fs')
const fil1 = path.join(__dirname, './test/a.txt')
const fil2 = path.join(__dirname, './test/b.txt')
const fil3 = path.join(__dirname, './test/c.txt')


let p1 = new Promise((resolve, reject) => {
  fs.readFile(fil1, 'utf-8', (error, data) => {
    if (error) {
      // 读取失败。执行reject函数
      return reject(error)
    }
    // 读取成功 执行resolve函数
    resolve(data)
  })
})
let p2 = new Promise((resolve, reject) => {
  fs.readFile(fil2, 'utf-8', (error, data) => {
    if (error) {
      // 读取失败。执行reject函数
      return reject(error)
    }
    // 读取成功 执行resolve函数
    resolve(data)
  })
})
let p3 = new Promise((resolve, reject) => {
  fs.readFile(fil3, 'utf-8', (error, data) => {
    if (error) {
      // 读取失败。执行reject函数
      return reject(error)
    }
    // 读取成功 执行resolve函数
    resolve(data)
  })
})

let str = ''
// 如果返回值是promise对象,下一个then里面函数的形参接收的不是这个promise对象,而是这个promise对象内部的调用resolve函数的参数或者reject函数的参数

p1.then(
  (data) => {
    str += data;
    // 读取第二个文件
    return p2
  },
  (error) => {
    // 读取失败,打印错误信息
    console.log(error.message);
  }
).then(
  (data) => {
    str += data;
    // 读取第三个个文件
    return p3
  },
  (error) => {
    // 读取失败,打印错误信息
    console.log(error.message);
  }
).then(
  (data) => {
    str += data;
    // 输出读取到的文件内容
    console.log(str);
  },
  (error) => {
    // 读取失败,打印错误信息
    console.log(error.message);
  }
);

使用util内置模块结合promise更优雅的完成文件读写


// 导入util
const util = require('util')
const path = require('path')
const fs = require('fs')
const fil1 = path.join(__dirname, './test/a.txt')
const fil2 = path.join(__dirname, './test/b.txt')
const fil3 = path.join(__dirname, './test/c.txt')


/* 
传入一个遵循常见的错误优先的回调风格的函数
(即以一个 (err, value) => ... 回调作为最后一个参数),
并且返回一个返回 promise 的版本。

  什么是错误优先: 比如  if (error) 作为第一个判断
*/
// 使用util.promisify() 返回一个Promise对象
let readFilePromise = util.promisify(fs.readFile);
// 上面的一行代码 就会把对象包装成下面的这种样子
/* function readFilePromise(filePath){
  return new Promise((resolve, reject) => {
    fs.readFile(filePath, 'utf-8', (error, data) => {
      if (error) {
        // 读取失败。执行reject函数
        return reject(error)
      }
      // 读取成功 执行resolve函数
      resolve(data)
    })
  })
} */

// 如果需要将最后读取的内容写入到文件中,只需要更改传递到promisify对象的参数即可
let writeFilePromise = util.promisify(fs.writeFile)

// 接收读取的内容
let str = ''
// 如果返回值是promise对象,下一个then里面函数的形参接收的不是这个promise对象,而是这个promise对象内部的调用resolve函数的参数或者reject函数的参数

readFilePromise(fil1).then(
  (data) => {
    str += data;
    // 读取第二个文件
    return readFilePromise(fil2)
  },
  (error) => {
    // 读取失败,打印错误信息
    console.log(error.message);
  }
).then(
  (data) => {
    str += data;
    // 读取第三个个文件
    return readFilePromise(fil3)
  },
  (error) => {
    // 读取失败,打印错误信息
    console.log(error.message);
  }
).then(
  (data) => {
    str += data;
    // 输出读取到的文件内容
    console.log(str);
    // 读取成功,将内容写入到文件中
    return writeFilePromise(path.join(__dirname,'./test/data.txt'),str)
  },
  (error) => {
    // 读取失败,打印错误信息
    console.log(error.message);
  }
).then(()=>{
  console.log('写入数据成功!');
},(error)=>{
  console.log(error.message);
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尤雨东

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值