前言
老生常谈promise
对于promise大部分人应该不陌生了,他是ES6的新特性之一,如果你是一个追求潮流的coder那么你应该用过axios请求方式,这个向后台发送请求的方式就用到了promise
我接触promise是一年前,部门的程序员会轮流培训,刚好当时我在看一些关于axios的东西,就准备培训一些关于promise的知识,所以我就找了很多关于promise的博客,看的也是云里雾里,可想而知培训的效果也不是很好
promise再探
promise很火,可以说是程序员居家旅行必备的技能之一了,所以说对于这样的东西,我们最好还是吃透它,这样才不会在代码当中迷失。
promise的作用
大多数人开发的过程中应该都会遇到一些异步的问题,比如我们必须等请求接口返回数据后才去做另外一些事情,我们都是通过回调函数来做
大部分好的情况是只需要等待一个异步的结果就可以去做一些事情,那么极端的情况是不同的异步嵌套,让我们的代码看上去就像一个金字塔,一层层的异步嵌套让我们头皮发麻,这种情况被我们称为回调地狱
fs.readFile('./sample.txt', 'utf-8', (err, content) => {
let keyword = content.substring(0, 5);
db.find(`select * from sample where kw = ${keyword}`, (err, res) => {
get(`/sampleget?count=${res.length}`, data => {
console.log(data);
});
});
});
回调的缺点
- 嵌套太深,难以维护
- 无法正常使用return和throw
- 无法正常检索出堆栈信息
promise就可以解决这些问题,可以让我们的代码跟优雅更具有可读性,给promise下个定义
promise是异步编程的一种解决方案,比回调函数更何理更强大
promise是一个代理对象,它和原先的操作并未关系,我们只需要把原先的操作放入执行器里
它通过一个回调函数,然后把其它的回调全部基于此回调函数
我们从使用层面上再来定义以下promise
- 主要用于异步计算
- 可以将异步操作队列化,让程序按照期望的顺序来执行,返回符合预期的结果
- 可以在对象之间传递和操作promise,帮助我们处理队列
同步和异步
大家都知道同步和异步,但是让你给他下个定义你知道吗?
一般而言,操作分为两种发出调用和得到结果,发出调用立即得到结果为同步,发出调用,无法立即得到结果,需要一些额外的操作才能得到预期的结果为异步。同步是在发出调用后一直等待程序是阻塞状态,异步发出调用后程序可以继续执行
异步操作的常见用法
- 事件侦听与响应
dom.addEventListener(type,callback)
$(dom).on(type,callback)
- 在浏览器中异步操作以事件为主
promise的三种状态
- pendding 实例化时候的状态
- fullfilled 操作成功后
- rejected 被否决操作失败
promise实例的后两种状态一经改变后不会再次改变,比如状态改成fullfilled不会在改成rejected
promise的结构
new Promise((resolve,reject)=>{
//此处执行一段异步代码 (这个部分被称为执行器)
//异步处理有结果之后执行对应的
resolve() //操作成功调用此回调,把promise实例的状态改成fullfilled
reject() //操作失败调用此回调,把promise实例的状态改成rejected
}).then((res,rej) => {
})
在then函数里返回一个新的promise,then支持两个参数(这个地方有一个坑 因为需要手动return),分别对应上一个promise实例的两个回调
then可以链式的调用,当前面一个promise的状态改变时,后面的then会根据前面一个promise的状态执行对应状态的回调
借用慕课网老师的一张图,看一下整个流程
- 实例化promise
- 执行器执行一段异步代码
- 判断异步代码执行成功或者失败分别调用resolve()或者rejected()
- resolve()或者rejected()改变promise实例的状态fullfilled或者rejected
- 执行then里面的对应promise状态的回调,fullfilled执行res(),rejected执行rej()
- then返回新的promise(需要使用return关键字)
- 下一个then会根据新返回来的promise的实例执行对应状态的res()或者rej()
new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('hello')
},3000)
}).then(
res =>{
return res+ ' world'
}
).then(
res =>{
console.log(res) // hello world
}
).catch(
err=>{
console.log(err)
}
)
就先简单介绍到这里吧
下周我会写一些用法,以及使用过程中常用的错误
网友评论