是什么
是一个构造函数,用来封装一个异步操作,并可以获得其结果
使用场景-异步编程:
fs文件操作
数据库操作(mongoDb)
Ajax
定时器
promise之前使用回调函数处理异步编程
为什么要用promise
- 指定回调函数的方式更加灵活
- 旧的:必须在启动异步任务前指定回调函数
- promise:启动异步任务 -> 返回promise对象 -> 给promise对象绑定回调函数(甚至可以在异步任务结束之后指定一个或多个)
- 支持链式调用,解决回调地狱的问题
promise的使用
1、构造
promise是一个构造函数,参数是一个函数,也就是将被异步执行的函数,该函数中有两个参数:
- resolve:函数执行成功之后调用,仅将promise对象的状态设置为「成功」
- reject:函数执行失败之后调用,仅将promise对象的状态设置为「失败」
const p = new Promise((resolve,reject)=>{
setTimeout(()=>{
// let n = rand(1,100);
let n = 10;
if(n <= 30){
resolve(n);//将promise对象的状态设置为「成功」,可以带出参数,供后面的then 回调函数 中使用
}else{
reject(n);//将promise对象的状态设置为「失败」,可以带出参数,供后面的then 回调函数 中使用
}
},1000);
});
2、调用then方法
指定回调函数,then方法有两个参数:
- param1:promise对象是成功时的回调函数,即异步方法成功后的回调
- param2:promise对象是失败时的回调函数,即异步方法失败后的回调
p.then((value)=>{
console.log('恭喜,中奖号码为:'+value);
},(reason)=>{
console.log('加油,您的号码为:'+reason);
})
常见问题
- 当用then为一个promise对象指定多个回调时,当promise的状态改变时,所有的回调都会执行
- promise改变状态和指定回调方法的先后问题?
- 当promise对象的执行器(即参数,函数)是一个同步任务时(直接调用resolve()/reject()),先改变promise状态,再指定回调
- 当promise对象的执行器(即参数,函数)是一个异步任务时(比如设置定时器),先指定回调,再改变promise状态
promise对象
状态 promiseState
状态值
是promise实例对象中内置的一个属性:promiseState
- pending 未决定的,初始化的默认值
- resolved / fullfilled 成功
- rejected 失败
状态的改变
- 从pending变为resolved
- 从pending变为rejected
说明:
- 状态的改变只有这两种,且一个promise对象的状态值只能被改变一次
- 无论成功还是失败,都会有一个结果数据
- 成功的结果数据一般称为value,失败的结果数据一般称为reason
结果属性 PromiseResult
存储promise对象成功或失败的结果,也就是异步任务成功或失败的结果
只有resolve()、reject() 两个函数可以对promiseResult进行修改
promise执行流程

API
Promise.resolve()
Promise函数对象级别的方法
使用:Promise.resolve(value=>{})
value:成功的数据或Promise对象
- 如果传入的参数不是Promise对象,则返回结果为一个成功的Promise对象
- 如果传入的参数是Promise对象,则参数的结果决定了resolve()的结果
结果:返回一个成功或失败的Promise对象
Promise.reject()
Promise函数对象级别的方法
使用:Promise.reject(reason=>{})
结果:返回一个失败的Promise对象,无论参数是什么
Promise.all()
参数:promises:包含n个promise的数组
结果:返回一个新的promise对象,只有所有的promise都成功才返回成功,只要有一个失败就直接失败;结果值是promise数组的结果组成的数组
Promise.race()
参数:promises:包含n个promise的数组
结果:返回一个新的promise,第一个完成的promise对象的结果就是最终的结果状态
promise的链式调用
利用then() 返回的是一个promise对象进行实现
1、使用
let p2 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('ok');
},1000)
});
//链式调用
p2.then(value=>{
return new Promise((resolve,reject)=>{
resolve('success');
})
}).then(value=>{
console.log(value)
}).then(value=>{
console.log(value)
})
2、异常穿透
在then链式调用的最后指定失败的回调,前面出现了任何问题,都会传到最后失败的回调中处理
let p2 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('ok');
},1000)
});
p2.then(value=>{
return new Promise((resolve,reject)=>{
resolve('success');
})
}).then(value=>{
console.log(value);
}).then(value=>{
console.log(value);
}).catch(reason=>{
console.warn(reason);
})
3、中断promise链
当使用promise的then链式调用时,在中间中断,不再调用后面的回调函数
方法:返回一个pending状态的promise对象
return new Promise(()=>{})
async函数和await表达式
结合使用无需再写回调函数!
写法形式类似于同步,但内部是异步执行的
async
- 用于修饰一个函数
- 函数的返回值是一个promise对象
- promise对象的结果由async函数执行的返回值决定
-
- 如果返回值是一个非promise类型的数据,结果就是一个成功的promise对象,结果值就是return的值
- 如果返回值是一个promise类型的数据,return的结果就决定了函数的返回结果
- 抛出异常,返回结果是失败的promise对象
await表达式
- await右侧的表达式一般是一个promise对象,但也可以是其他值
- 若表达式的右侧是promise对象,await返回的是promise成功的值
- 若表达式是其他值,直接将此值作为await的返回值
- await必须写在async函数中,但async函数中可以没有await
- 如果await的promise失败了,就会跑出异常,需要通过try...catch捕获处理
- await会阻塞进程,会暂停当前async function()的执行,等待promise执行完成
817

被折叠的 条评论
为什么被折叠?



