Promise:基本使用

问题导向

Promise是什么? 如何使用?

如果你都有了答案,可以忽略本文章,或去JS学习地图寻找更多答案


Promise是什么

//是什么?
简单说:JS中异步编程的解决方案
从语法上来说:Promise是一个构造函数
从功能上来说:Promise对象用来封装一个异步操作并可以获取其结果

//为什么?
1.指定回调函数的方式更加灵活
    回调嵌套:必须在启动异步任务前指定成功或失败的回调函数,才能拿到结果
    promise:启动异步任务后,返回promise对象,想拿结果的时候在指定回调
        prosemi.then(successCallback, failCallBack)
2.支持链式调用,可以解决回调函数嵌套问题,也就是回调地狱
   回调地狱:为了任务的执行顺序
   回调地狱的缺点:不便于阅读和异常处理

//如何用?

Promise-API

Promise 构造函数 new Promise(excutor)
excutor函数:执行器 (resolve, reject) => {}  //内部同步回调
resolve函数: 成功回调
reject函数: 失败回调

原型方法:
Promise.prototype.then(value => {}, reason => {})  //异步回调
Promise.prototype.catch(err => {})                 //then失败回调的语法糖
Promise.prototype.finally(() => {})                //总会执行
    
静态方法:
Promise.resolve()
Promise.reject()
Promise.all([])    //执行多个任务,有一个失败,就全部失败
Promise.race([])   //执行多个任务,只返回第一个成功的任务
Promise.allSettled([])  //执行多个任务,无论是失败状态还是成功状态,都会以数组对象的方式返回数据

语法糖:
async await + try catch

Promise状态改变

Promise的设计采用三种状态来标记一个任务是成功还是失败,
它不但会保存任务的执行结果,
而且,会根据任务状态进入相应的流程

注意:
一个Promise对象链式调用一次只能改变一次状态,且状态不可逆

三种状态:
new Promise:pending  //准备态
resolved  //成功态
rejected  //失败态

改变状态:
resolve():如果当前是pendding,会变成resolved
reject(): 如果当前是pendding,会变成rejected
抛出异常:  会变成rejected,被catch捕抓

异步回调

两种类型的回调函数

//回调函数
三个条件:
1.自己定义
2.自己不调用
3.最终会执行
如:setTimeout(() => {console.log('回调')}, 1000)

//同步回调
arr.forEach(item => {console.log(item)})
console.log('后执行,因为forEach是同步回调')

//异步回调
setTimeout(() => {console.log('回调')}, 0)
console.log('先执行,因为setTimeout是异步回调')

异步的问题

//异步任务,无法保证执行顺序
fs.readFile('./data/a.txt','utf8',(err,data) => {
   if(err) throw err
   console.log(data)
})
​
fs.readFile('./data/b.txt','utf8',(err,data) => {
   if(err) throw err
   console.log(data)
})
​
fs.readFile('./data/c.txt','utf8', (err,data) => {
   if(err) throw err
   console.log(data)
})//通过回调嵌套的方式来保证顺序
//回调地狱:造成多层嵌套,代码混乱,难以理解
fs.readFile('./data/a.txt','utf8',(err,data) => {
   if(err) throw err
   console.log(data)
   fs.readFile('./data/b.txt','utf8',(err,data) => {
        if(err) throw err
        console.log(data)
        fs.readFile('./data/c.txt','utf8',(err,data) => {
              if(err) throw err
              console.log(data)
        })
    })
})

使用promise解决问题

管式代码,容易阅读,错误统一处理

封装
function readFile(path){
	return new Promise((resolve,reject) => {
		fs.readFile(path,'utf8',(err,data) => {
			if(err) {
				reject(err)
			}
			resolve(data)
		}
	})
}

使用
readFile('./data/a.txt')
.then((data) => {
  console.log(data)
  return readFile('./data/b.txt')
})
.then((data) => {
  console.log(data)
  return readFile('./data/c.txt')
})
.then((data) => {
  console.log(data)
})
.catch((err) => {
  console.log(err)
})

Promise-API详解

then

第一个参数是:成功回调,可写null,只写失败回调
第二个参数是:失败回调,可选

new Promise((resolve,reject) => {
	setTimeout(() => {
       if (Math.random() * 10 > 5) {
           resolve('成功')
      }
       reject('失败')
  }, 1000)
}).then((data) => {
   console.log(data)
},(err) => {
   console.log(err)
})

catch

可以统一接收错误,放到代码的后面,
如果前面没有错误的处理(then的第二个参数)
就走catch,如果有就走错误的处理(单独处理)

new Promise((resolve,reject) => {
	setTimeout(() => {
       if (Math.random() * 10 > 5) {
           resolve('成功')
      }
       reject('失败')
  }, 1000)
}).then((data) => {
   console.log(data)
}).catch((err) => {
	console.log(err)
})

finally

无论成功失败都会执行

new Promise((resolve,reject) => {
	setTimeout(() => {
       if (Math.random() * 10 > 5) {
           resolve('成功')
      }
       reject('失败')
  }, 1000)
}).then((data) => {
   console.log(data)
}).catch((err) => {
	console.log(err)
}).finally(() => {
	console.log(‘无论成功失败都会执行’)
})

Promise.reject() :在成功态抛出异常

new Promise(resolve => {
   resolve('哈哈哈')
}).then(value => {
   if(value !== '成功'){
       return Promise.reject('参数错误')
  }
   console.log(value)
}).catch(error => {
   console.log(error)
})

Promise.all

处理多个请求,如果其中有一个是失败状态,Promise.all的状态也会变成失败,就会执行失败逻辑,用来批量处理数据
成功:返回全部promise成功的数组
失败:返回失败的promise

const p1 = new Promise((resolve, reject) => {
   if (Math.random() > 0.5) {
       resolve('第一个成功')
  }
   reject('第一个失败')
})
const p2 = new Promise((resolve, reject) => {
   if (Math.random() > 0.5) {
       resolve('第二个成功')
  }
   reject('第二个失败')
})
Promise.all([p1, p2])
  .then((result) => {
   console.log(result)
})
  .catch((error) => {
   console.log(error)
})

Promise.allSettled

处理多个请求,无论是失败状态还是成功状态,都会以数组对象的方式返回数据

const p1 = new Promise((resolve, reject) => {
   if (Math.random() > 0.5) {
       resolve('第一个成功')
  }
   reject('第一个失败')
})
const p2 = new Promise((resolve, reject) => {
   if (Math.random() > 0.5) {
       resolve('第二个成功')
  }
   reject('第二个失败')
})
Promise.allSettled([p1, p2])
  .then((result) => {
   console.log(result)
})
  .catch((error) => {
   console.log(error)
})


返回结果如下:
[
  {status:'fulfilled',value:'第一次成功'}{status:'rejected',reason:'第二次失败'}
]


//实际业务
const promises = ['大神','乔伊'].map(name => {
   return ajax(`xxx${name}`)
})
Promise.allSettled(promises).then(values => {
   let users = values.filter(user => {
       return user.status === 'fulfilled'
  })
   console.log(users)
})

Promise.race

处理多个请求,哪个返回快,就用哪个

const p1 = new Promise((resolve, reject) => {
   setTimeout(() => {
       resolve('第一个异步')
  }, 1000)
})
const p2 = new Promise((resolve, reject) => {
   setTimeout(() => {
       resolve('第二个异步')
  }, 200)
})

Promise.race([p1, p2])
  .then((result) => {
   console.log(result)
})
  .catch((error) => {
   console.log(error)
})

学习更多

JS学习地图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值