看完这个,你就懂了Promise的一切
Opened this issue · 0 comments
1.Promise的含义
promise 是前端的一种异步编程的解决方案,比传统的解决方案(回调函数和事件)更合理和更强大。ES6将其写进了语言标准,提供了原声的Promise对象
所谓promise,就是保存一个未来才会结束的事件(通常是异步操作),
- promise对象的状态不受外界影响。promise对象代表一个异步操作,有三种状态:pending、fulfilled、rejected,只有异步操作的结果,可以决定当前是哪一种状态,其他操作都不能改变这种状态
- 一但状态改变,就不会再变。promise的状态改变只有两种可能:从pending变为fulfilled和从pending变为rejected
- promise也有一些缺点。首先,无法取消promise,一但新建他就会立即执行,无法中途取消;其次,如果不设置回调函数,promise内部抛出的错误,不会反应到外部;第三,当处于pending状态时,无法得知目前进展到哪一个阶段
2.基本用法
ES6规定,Promise是一个构造函数,用来生成promise实例
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
promise生成实例后,可以用then方法分别制定resolve状态和reject状态的回调函数
promise.then(function(value) {
// success
}, function(error) {
// failure
});
3.then()
promise具有then方法。也就是说,then方法定义在原型对象 Promise.prototype上的。它的作用是为了Promise实例添加状态改变时的回调函数。前面说过,then方法的第一个参数是resolve状态的回调,第二个参数是reject状态的回调,他们都是可选的
then方法返回的是一个新的Promise实例(是新的,不是原来的),因此可采用链式写法,即then方法后面再调用另一个then方法
getJSON("/posts.json").then(function(json) {
return json.post;
}).then(function(post) {
// ...
});
上面带嘛使用then方法,依次制定了两个回调函数,第一个回调函数执行完成过后,会将返回结果作为参数,传入第二个回调函数。
4.catch()
catch()是.then(null, rejection)或.then(undefined, rejection)的别名,用于制定发生错误时的回调函数
getJSON('/posts.json').then(function(posts) {
// ...
}).catch(function(error) {
// 处理 getJSON 和 前一个回调函数运行时发生的错误
console.log('发生错误!', error);
});
p.then((val) => console.log('fulfilled:', val))
.catch((err) => console.log('rejected', err));
// 等同于
p.then((val) => console.log('fulfilled:', val))
.then(null, (err) => console.log("rejected:", err));
5.finally()
finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
finally方法的回调函数不接受任何参数,这意味着没有办法知道,前面的promise状态到底是fulfilled还是rejected。这表明,finally方法面的操作,应该与状态无关的,不依赖于promise的执行结果
finally本质上是then方法的特例
6.all()
promise.all()方法用于将多个Promise实例,包装成一个新的promise实例
const p = Promise.all([p1,p2,p3])
上面代码中,promise.all()方法接受一个数组作为参数,p1、p2、p3都是promise实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为promise实例,再进一步处理。另外,Promise.all()方法的参数可以不是数组,但必须具有Iterator接口,且返回的每一个成员都是Promise实例
p的状态由p1、p2、p3决定,分成两种情况。
1.只有p1、p2、p3的状态变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数
2.只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数
7.race()
const p = Promise.race([p1, p2, p3]);
上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
8.allSettled()
allSettled()方法接受一组promise实例作为参数,包装成一个新的promise实例。只有等到所有参数实例都返回结果,不管是fulfilled还是reject,实例才会结束
const promises = [
fetch('/api-1'),
fetch('/api-2'),
fetch('/api-3'),
];
await Promise.allSettled(promises);
removeLoadingIndicator();
上面带嘛对服务器发出三个请求,等到三个请求都结束,不管请求成功还是失败,都会返回
9.any()
该方法接受一组promise实例作为参数,包装一个新的promise实例返回。只要参数实力有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成reject状态,包装实例就会变成rejected状态
resolve()
有时需要将现有对象转为Promise对象,promise.resolve()方法就起到这个作用