Promise处理异步回调

77 篇文章 7 订阅

Promise处理异步回调

Promise 是一个对象,是用来处理异步操作的,可以让异步调用的代码更加优雅、美观、有利于阅读。

背景

​ node.js 采用异步回调的方式来处理需要等待的事件,使得代码会继续往下执行,不用在某个地方等待着。但是当有很多回调的时候,比如这个回调执行完需要去执行下个回调,然后接着再执行下个回调,这样就会造成回调层层嵌套,代码不清晰,很容易进入“回调地狱”,示例如下:

对3个文件进行读取操作

const fs = require('fs')

// 3个进程没有顺序,"异步"方式读取文件
// 由于电脑资源分配不均匀,以下3个进程执行前后顺序没有保障
 fs.readFile('./files/01.txt','utf8',function(err,data){
   if(err){return console.log('文件错误了:'+err)}
   console.log(data)
 })
 fs.readFile('./files/02.txt','utf8',function(err,data){
   if(err){return console.log('文件错误了:'+err)}
   console.log(data)
 })
 fs.readFile('./files/03.txt','utf8',function(err,data){
   if(err){return console.log('文件错误了:'+err)}
   console.log(data)
 })

保障各个异步过程顺序执行(嵌套调用)

// 以下代码不好,嵌套调用层次深,形成回调地狱效果,代码不好维护
 fs.readFile('./files/01.txt','utf8',function(err,data){
   if(err){return console.log('文件错误了:'+err)}
   console.log(data)
   fs.readFile('./files/02.txt','utf8',function(err,data){
     if(err){return console.log('文件错误了:'+err)}
     console.log(data)
     fs.readFile('./files/03.txt','utf8',function(err,data){
       if(err){return console.log('文件错误了:'+err)}
       console.log(data)
     })
   })
 })

es6新出的promise对象以及es7的async await 可以处理异步操作顺序执行。

相关异步操作

  1. axios(ajax) 返回一个Promise对象
  2. setTimeout 定时器
  3. fs.readFile() 文件读取

异步

在同一个时间中,可以发送多个进程进行执行。

同步

在同一个时间点,只有一个进程在执行。

基本介绍

Promise的三种状态

  1. pending(进行中)
  2. resolved(完成)
  3. rejected(失败)

只有异步返回的结果可以改变其状态。所以,promise的过程一般只有两种:

  1. pending->resolved

  2. pending->rejected。

Promise的作用

  1. 解决了异步调用彼此嵌套的回调地狱问题。
  2. 解决了多个异步过程顺序执行问题。

使用方法

​ promise对象有一个比较常用的then方法,用来执行回调函数,then方法接受两个参数,第一个是成功的resolved的回调,另一个是失败rejected的回调,第二个失败的回调参数可选。并且then方法里也可以返回promise对象,这样就可以链式调用了。

// 创建Promise对象
var p = new Promise(function(resolve,reject){
  if(异步操作成功){
    // resolve: 异步操作成功的回调函数
  	resolve(result)
  }else{
    // reject:异步操作失败的回调函数
    reject(error)
  }
})

// 对Promise对象结果进行处理
p
  .then(
  	function(res){
    	// res 与 result一致,代表成功输出结果
  	}
  )
  .catch(
  	function(err){
      // err 与 error一致,代表失败输出结果
    }
  )

案例应用

对3个文件进行读取操作

// Promise介入(还没有顺序保障)
function getContent(filename){
   var p = new Promise(function(){
     // 异步操作
     fs.readFile(filename,'utf8',function(err,data){
       if(err){return console.log('文件错误了:'+err)}
       console.log(data)
     })
   })
 }

 getContent('./files/01.txt')
 getContent('./files/02.txt')
 getContent('./files/03.txt')

在Promise内部不要设置"业务逻辑"代码,同时内部把promise对象进行return返回:

function getContent(filename){
  // resolve:代表异步成功执行的回调函数
  // reject:代表异步失败执行的回调函数
  return new Promise(function(resolve,reject){
    // 异步操作
    fs.readFile(filename,'utf8',function(err,data){
      if(err){return reject('文件错误了:'+err)}
      resolve(data)
    })
  })
}

多个异步操作顺序执行、没有回调地狱:

getContent('./files/01.txt')
  .then(function(rst){
    console.log(rst) 
    // 返回一个实体Promise对象
    // promise对象调用then完毕还会返回一个promise对象
    // 因此可以继续调用then方法,默认情况promise对象是空的
    // 如果在then内部return返回一个实体的Promise对象,则该then就把其返回了(就不是空的Promise对象了)
    return getContent('./files/02.txt')
  })
  .then(function(rst){
    console.log(rst) 
    return getContent('./files/03.txt')
  })
  .then(function(rst){
    console.log(rst) 
  })
  .catch(function(cuo){
    // 统一接收以上各个异步进程的错误信息
    console.log(cuo)
  })

Promise对象,可以调用then、catch方法:

var p1 = getContent('./files/012323.txt')
console.log(p1) // Promise { <pending> }

// [Promise对象可以调用then和catch方法]接收 resolve 和 reject,进而获得相关的信息
 p1
   .then(function(rst){
     console.log(rst) 
   })
   .catch(function(cuo){
     console.log(cuo)
   })
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值