IT培训-高端面授IT培训机构
云和教育:云和数据集团高端IT职业教育品牌
  • 华为
    授权培训中心
  • 腾讯云
    一级认证培训中心
  • 百度营销大学
    豫陕深授权运营中心
  • Oracle甲骨文
    OAEP中心
  • Microsoft Azure
    微软云合作伙伴
  • Unity公司
    战略合作伙伴
  • 普华基础软件
    战略合作伙伴
  • 新开普(股票代码300248)
    旗下丹诚开普投资
  • 中国互联网百强企业锐之旗
    旗下锐旗资本投资

Promise是怎样读取文件内容的?

  • 发布时间:
    2022-12-08
  • 版权所有:
    云和教育
  • 分享:

为了解决回调地狱的问题,ES6(ECMAScript 2015)中新增了 Promise 的概念,Promise 是一个构造函数,可以用来创建 Promise 的实例 const p = new Promise(),new 出来的 Promise 实例对象,代表一个异步操作。

Promise.prototype 上包含一个 .then() 方法, 每一次 new Promise() 构造函数得到的实例对象,都可以通过原型链的方式访问到 .then() 方法,例如 p.then()。

同时.then() 方法用来预先指定成功和失败的回调函数

p.then(成功的回调函数,失败的回调函数)

p.then(result => { }, error => { })

调用 .then() 方法时,成功的回调函数是必选的、失败的回调函数是可选的。基于以上的理论,我们来看Promise的常见用法。

基于回调函数按顺序读取文件内容,具体代码如下:

//读取文件1.txt
fs.readFile('./files/1.txt', 'utf8', (err1, r1) => {
  if (err1) return console.log(err1.message) //读取文件1失取
  console, log(r1) //读取文件 1 成功
  //读取文件2.txt
  fs.readFile('./files/2.txt', 'utf8', (err2, r2) => { //诗取文件 2 失败
    if (err2) return console.log(err2.message)
    console.log(r2) //读取文件 2 成功
    //读取文件3.txt
    fs.readFile('./files/3.txt', 'utf8', (err3, r3) => {
     if (err3) return console.log(err3.message) //读取文件 3失败
      console.log(r3) //读取文件 3  成功
    })
  })
})

基于 then-fs 读取文件内容

由于 node.js 官方提供的 fs 模块仅支持以回调函数的方式读取文件,不支持 Promise 的调用方式。因此,需要先运行如下的命令,安装 then-fs 这个第三方包,从而支持我们基于 Promise 的方式读取文件的内容。

npm install then-fs

调用then-fs提供的readFile()方法,可以异步地读取文件的内容,C的返回值是Promise的实例对象。因此可以调用.then()方法为每个Promise异步操作指定成功和失败之后的回调函数。示例代码如下:

then-fs 的基本使用

调用 then-fs 提供的 readFile() 方法,可以异步地读取文件的内容,它的返回值是 Promise 的实例对象。因此可以调用 .then() 方法为每个 Promise 异步操作指定成功和失败之后的回调函数。示例代码如下:

/★★
*基于Promise的方式读取文件
*/
impoik: thenFs from 'then-fs'
//注意:.then()中的失败回调是可选的,可以被省略
thenFs.readFile('./files/1.txt','utf8').then(r1=>{console.log(r1)},err1 =>{console.log(err1.message)})
thenFs.readFile('./files/2.txt','utf8').then(r2 =>{console.log(r2)},err2 =>{console.log(err2.message)})
thenFs.readFile('./files/3.txt','utf8').then(r3 =>{ console.log(r3)},err3 =>{console.log(err3.message)})

注意:上述的代码无法保证文件的读取顺序,需要做进一步的改进!

.then() 方法的特性

如果上一个 .then() 方法中返回了一个新的 Promise 实例对象,则可以通过下一个 .then() 继续进行处理。通过 .then() 方法的链式调用,就解决了回调地狱的问题。

基于 Promise 按顺序读取文件的内容

Promise 支持链式调用,从而来解决回调地狱的问题。示例代码如下:

thenFs.readFile('./files/1.txt''utf8')// 1.返回值是Promise的实例对象
  .then((r1)=>{// 2.通过.then为第一个Promise实例指定成功之后的回调函数
    console.log(r1)
    return thenFs.readFile('./files/2.txt'/utf8')// 3.在第一个.then中返回一个新的Promise实例对象
  })
  .then((r2)=>{//4.继续调用.then,为上一个.then 的返回值(新的Promise 实例)指定成功之后的回调函数
    console.log(r2)
    return thenFs.readFile('./files/3.txt','utf8')// 5.在第二个.then中再返回一个新的Promise实例对象
  })
  .then((r3)=>{// 6.继续调用.then,为上一个.then 的返回值(新的Promise实例)指定成功之后的回调函数
    console.log(r3)
  })

通过 .catch 捕获错误

在 Promise 的链式操作中如果发生了错误,可以使用 Promise.prototype.catch 方法进行捕获和处理:

thenFs.readFile('./files/11.txt''utf8'//文件不存在导致读取失败,后面的3个.then 都不执行
  .then(r1 =>{
    console.log(r1)
    return thenFs.readFile('./files/2.txt','utf8')
  })
  .then(r2=> {
    console.log(r2)
    return thenFs.readFile('./files/3.txt', 'utf8')
  })
  .then(r3 =>(
    console.log(r3)
  })
  .catch(err =>{//捕获第1行发生的错误,并输出错误的消息
    console.log(err.message)
  })

Promise.all() 方法

Promise.all() 方法会发起并行的 Promise 异步操作,等所有的异步操作全部结束后才会执行下一步的 .then操作(等待机制)。示例代码如下:

//1.定义一个数组,存放3个读文件的异步操作
const promiseArr = [
  thets.readFile('./files/11.txt','utf8').
  thenFs.readFile('./files/2.txt','utf8'),
  thenFs.readFile('./files/3.txt','utf8'),
]
// 2.将 Promise的数组,作为Promise.all()的参数
Promise.all(promiseArr)
  .then(([r1,r2,r3]=>{//2.1所有文件读取成功(等待机制)
    console.log(r1, r2, r3)
  })
.catch(err =>{// 2.2捕获 Promise异步操作中的错误
    console.log(err.message)
  })

注意:数组中 Promise 实例的顺序,就是最终结果的顺序!

Promise.race() 方法

Promise.race() 方法会发起并行的 Promise 异步操作,只要任何一个异步操作完成,就立即执行下一步的 .then 操作(赛跑机制)。示例代码如下:

//1.定义一个数组,存放3个读文件的异步操作
const promiseArr =[
  thenFs.readFile('./files/1.txt', 'utf8'),
  thenFs.readFile('./files/2.txt', 'utf8').
  thenFs.readFile('./files/3.txt', 'utf8').
]
// 2.将 Promise 的数组,作为 Promise.race()的参数
Pronise.race(promiseArr)
  .then((result)=>{//2.1只要任何一个异步操作完成,就立即执行成功的回调函数(赛跑机制)
    console.log(result)
  })
  .catch(err =>{// 2.2捕获Promise 异步操作中的错误
    console.log(err.message)
  })