Promise功能和作用
promise是异步编程的解决方案,比回调函数和事件更合理强大。
promise的精髓是“状态”,通过维护状态,传递状态的方式调用回调函数,
promise有三种状态:pending,fulfiled,rejected。状态改变后不会再变。
主要解决的问题:
- 回调地狱的问题
- 支持并发的请求,获取请求的数据
执行时机
Promise创建实例后,会立即执行。
.then方法的回调在当前脚本的所有同步任务执行完时才会执行。
先执行同步任务,同步任务执行完成后才会执行 .then方法的任务
立即resolve的Promise在本轮事件循环的末尾执行。晚于本轮循环的同步任务。setTimeout(fn , 0)在下一轮时间轮换开始时执行。
用法
then方法链式操作:
.then 方法先接收状态,根据状态(fulfilled 或 rejected)执行对应的回调
接收两个参数(resolved的回调, rejected的回调)
其中rejected回调可以省略。
let p = new Promise((resolve, reject) =>
resolve('成功')
)
p.then(value => {
console.log(value);
return Promise.resolve('依然成功');
}, reason=>{
console.warn(reason);
})
.then((data) => {
console.log(data);
})
catch方法:
类似.then 方法第二个参数,是 .then(null, rejected)的别名。用来指定发生错误时的回调函数。
当异步操作抛出错误,用.catch 方法指定的回调来处理这个错误。
let p = new Promise((resolve, reject) => {
reject('error');
});
p.catch(reason => {
console.log(reason);
});
如果在执行resolve()的回调的时候,如果抛出异常(代码出错),不会报错卡死js,而是进入catch 方法中。
const promise = new Promise((resolve, reject) => {
resolve();
reject('error');
})
promise.then(() => {
console.log(3);
}).then(() => {
console.log(5)
}).catch(e => console.log(e))
此处的 reject('error'); 无效。
romise对象的错误具有“冒泡”性质,会一直向后传递,知道被捕获为止。错误总会被下一个catch语句捕获。
如果.then 方法中已经resolved,再抛出错误是无效的。
resolve 用法
将现有对象转为Promise对象。
有四种情况
reject用法:
Promise的状态设置为rejected,这样在then中就可以捕捉到,然后执行“失败”情况的回调。
let p3 = Promise.reject(new Promise((resolve, reject) => {
resolve('OK');
}));
console.log(p3);
all 的用法
以最后执行的为准执行回调。
let p1 = new Promise((resolve, reject) => {
resolve('ok');
})
let p2 = Promise.resolve('Success');
let p3 = Promise.resolve('oh yeah');
const result = Promise.all([p1,p2,p3]);
console.log(result);
有了all,你就可以并行执行多个异步操作,并且在一个回调中处理所有的返回数据
使用场景:所有的静态资源都加载完后,我们再进行页面的初始化。
只要数组元素:p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
all方法的效果实际上是「谁跑的慢,以谁为准执行回调」
race 的用法
以最先执行的为准,先执行完成的结果返回。
使用场景:可以用race给某个异步请求设置超时时间,并在超时之后执行相应的操作。
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ok');
}, 1000);
})
let p2 = Promise.resolve('Success');
let p3 = Promise.resolve('on Yeah');
const result = Promise.race([p1, p2, p3]);
console.log(result);