Promise的介绍
1. Promise的介绍
Promise是es6引入的异步编程的解决方法,从语法上说,Promise就是一个构造函数。从功能上说,Promise就是封装了一个异步操作,并可以获取其成功或失败的结果。
2. 常见的异步操作
- fs文件读取:require(“fs”).readFile(‘index.html’,(err,data)=>{})
- 数据库操作
- ajax请求:$.get(url,()=>{})
- setTimeout(()=>{},time)
- setInterval(()=>{},time)
3. Promise的优势:
- 指定回调函数的方式更加灵活
- 旧:必须在启动异步任务前指定
- promise:启动异步任务->返回promise对象-给promise对象绑定指定回调函数(甚至可以在异步任务结束后指定多个) - 支持链式调用,可以解决回调地狱问题
- 回调地狱:回调函数嵌套使用,外部回调函数异步执行的结果是嵌套的回调执行的条件
- 不便于阅读、不便于异常处理。
- 可以通过promise链式调用解决。
-
4. Promise对象
const promise = new Promise((resolve,reject)=>{
console.log(111)
});
console.log(promise);
/*
Promise {<pending>}
[[Prototype]]: Promise
[[PromiseState]]: "pending"
[[PromiseResult]]: undefined
*/
- promise的状态
- 实例对象中的一个属性,【PromiseState】
- pending—未决定的
- resolved/fullfilled—成功
- rejected—失败
- 状态只能从pending变为resolved/rejected,不能从resolved->rejected,rejected->resolved
- 状态只能改变一次
- promise 对象的值
- 实例对象中的另一个属性,【PromiseResult】,保存着对象[成功/失败]的结果。
- resolve
- reject
5. promise的工作流程
- 通过new Promise()创建一个promise对象,在promise内部封装异步操作。
- 如果异步操作成功,则调用resolve方法,并将promise的状态设置为resolved,并调用then()的第一个回调。返回一个新的promise对象。
- 如果异步操作失败,则调用reject方法,并将promise的状态设置为rejected,并调用then()的第二个回调。返回一个新的promise对象。
6. promise的API
let p = new Promise((resolve,reject)=>{
console.log(111);
})
console.log(222);
---先输出111后输出222
- Promise的构造函数:Promise(executor),
----executor函数:(resolve,reject)=>{@}
----resolve为成功的回调,reject为失败的回调
----executor会在Promise内部立即同步执行,异步操作在执行器中执行。 - Promise.prototype.then((onResolved,onReject)=>{}),分别是成功和失败的回调
- Promise.prototype.catch(reson=>{}):失败的回调
- Promise.resolve方法:(value)=>{},返回成功/失败的promise对象
- Promise.reject方法:返回一个失败的promise对象
- Promise.all:(promises)=>{},参数是一个数组,只有所有promise都成功才成功。只要有一个失败了就直接失败。
- Promise.race:(promises)=>{},参数是一个数组,第一个promise的状态绝对最后结果。
7. promise的几个关键问题
- 指定回调的方法 then() 或 catch()
- 修改对象的状态,调用resolve() 或 reject() 或 throw
let promise = new Promise((resolve,reject)=>{resolve('ok')})
let promise = new Promise((resolve,reject)=>{reject('fail')})
let promise = new Promise((resolve,reject)=>{throw 'error'})
- 能否执行多个回调:当promise改为对应状态时,都会调用
let promise = new Promise((resolve,reject)=>{
reject('ok')
})
promise.then((resolve)=>{
console.log("执行了-1")
}).then((resolve)=>{
console.log("执行了-2")
});
// 先输出"执行了-1",然后输出"执行了-2"
- 指定回调与改变状态的执行顺序
– 改变状态和指定回调的执行顺序,谁先谁后?
答:都有可能,正常情况是先指定回调函数在改变状态,但是也可以先改变状态再指定回调
– 如何先改变状态再指定回调?
- 在执行器中直接调用resolve()/reject()
- 延长更长时间才调用then()
– 什么时候才得到数据?
- 如果先指定回调,当状态改变时,回调函数就会被调用,得到数据
- 如果先改变状态,那当指定回调时,回调函数就会被调用,得到数据