ES6的Promise的理解和使用

561 阅读3分钟

Promise功能和作用

promise是异步编程的解决方案,比回调函数和事件更合理强大。

promise的精髓是“状态”,通过维护状态,传递状态的方式调用回调函数,

promise有三种状态:pending,fulfiled,rejected。状态改变后不会再变。

image.png

主要解决的问题:

  • 回调地狱的问题
  • 支持并发的请求,获取请求的数据

执行时机

Promise创建实例后,会立即执行。

.then方法的回调在当前脚本的所有同步任务执行完时才会执行。

先执行同步任务,同步任务执行完成后才会执行 .then方法的任务

立即resolve的Promise在本轮事件循环的末尾执行。晚于本轮循环的同步任务。setTimeout(fn , 0)在下一轮时间轮换开始时执行。

image.png

image.png

用法

image.png

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);
})

image.png

catch方法:

类似.then 方法第二个参数,是 .then(null, rejected)的别名。用来指定发生错误时的回调函数。

当异步操作抛出错误,用.catch 方法指定的回调来处理这个错误。

let p = new Promise((resolve, reject) => {
    reject('error');
});
p.catch(reason => {
    console.log(reason);
});

image.png

如果在执行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对象。

有四种情况

image.png

reject用法:

Promise的状态设置为rejected,这样在then中就可以捕捉到,然后执行“失败”情况的回调。

let p3 = Promise.reject(new Promise((resolve, reject) => {
    resolve('OK');
}));

console.log(p3);

image.png

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);

image.png 有了all,你就可以并行执行多个异步操作,并且在一个回调中处理所有的返回数据

使用场景:所有的静态资源都加载完后,我们再进行页面的初始化。

只要数组元素:p1p2p3之中有一个被rejectedp的状态就变成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);

image.png