一.什么是Promise?
Promise是JS异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步编程解决方案之一。
二.对于几种常见异步编程方案
先来回顾下我们经常用到的几种情况
1.回调函数
例子一:
$.get(url,(data) =>{
console.log(data)
}) //do something
例子二:
callback(){
console.log('do callbacks');
};
setTimeout(callback,300);
2.事件监听
例子一:
$elem.on(‘click’, doClick(){
//do something
});
3.发布/订阅
例子一:
//订阅
emitter.on('event1',function(message){console.log(message);})
//发布
emitter.emit('event1','I am message');
当我们需要发送多个异步请求 并且每个请求之间需要相互依赖 那这时 我们只能 以嵌套方式来解决 形成 "回调地狱”
$.get(url, data1 => {
console.log(data1)
$.get(data1.url, data2 => {
console.log(data1)
})
})
这样一来,在处理越多的异步逻辑时,就需要越深的回调嵌套,这种编码模式的问题主要有以下几个:
代码逻辑书写顺序与执行顺序不一致,不利于阅读与维护。
异步操作的顺序变更时,需要大规模的代码重构。
回调函数基本都是匿名函数,bug 追踪困难。
4.Promise对象
Promise 处理多个相互关联的异步请求,而我们Promise 可以更直观的方式 来解决 "回调地狱"
const request = url => {
return new Promise((resolve, reject) => {
$.get(url, data => {
resolve(data)
});
})
};
// 请求data1
request(url).then(data1 => {
return request(data1.url);
}).then(data2 => {
return request(data2.url);
}).then(data3 => {
console.log(data3);
}).catch(err => throw new Error(err));
三.Promise使用
promise对象状态不受外界影响,它有三种状态:
Pending:进行中
Fulfilled:已成功
Rejected:已失败
Promise状态一旦改变就不会再变,任何时候都可以得到这个结果。它的状态改变只有两种结果:
(1) promise 对象初始化状态为 pending
(2) 当调用resolve(成功),会由pending => fulfilled
(3) 当调用reject(失败),会由pending => rejected
* Promise对象状态不受外界影响,它有三种状态,只有异步操作的结果才能确定当前处于哪种状态,任何其他操作都不能改变这个状态。这也是Promise(承诺)的由来。
Promise缺点
1.无法取消Promise,一旦新建它就会立即执行,无法中途取消
2.如果不设置回调函数(没有捕获错误),Promise内部抛出的错误,不会反应到外部
3.当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)
四.Promise的API
我们先来看看console.dir(Promise)
这里,我们主要讲解几个方法:
1. Promise.prototype.constructor()
2. Promise.prototype.then()
3. Promise.prototype.catch()
4. Promise.prototype.finally()
5. Promise.all()
6. Promise.race()
4.1 Promise.prototype.constructor()
Promise接收一个函数作为参数,函数里有resolve和reject两个参数:
1. resolve方法的作用是将Promise的pending状态变为fulfilled,在异步操作成功之后调用,可以将异步返回的结果作为参数传递出去。
2. reject方法的作用是将Promise的pending状态变为rejected,在异步操作失败之后调用,可以将异步返回的结果作为参数传递出去。
他们之间只能有一个被执行,不会同时被执行,因为Promise只能保持一种状态。
4.2 Promise.prototype.then()
romise实例确定后,可以用then方法分别指定fulfilled状态和rejected状态的回调函数。它的基本用法如下:
then(onfulfilled,onrejected)方法中有两个参数,两个参数都是函数,
第一个参数执行的是resolve()方法(即异步成功后的回调方法)
第二参数执行的是reject()方法(即异步失败后的回调方法)(第二个参数可选)。它返回的是一个新的Promise对象。
4.3Promise.prototype.catch()
catch方法是.then(null,onrejected)的别名,用于指定发生错误时的回调函数。作用和then中的onrejected一样,不过它还可以捕获onfulfilled抛出的错,这是onrejected所无法做到的:
Promise错误具有"冒泡"的性质,如果不被捕获会一直往外抛,直到被捕获为止;而无法捕获在他们后面的Promise抛出的错。
4.4Promise.prototype.finally()
finally方法用于指定不管Promise对象最后状态如何,都会执行的操作。该方法是 ES2018 引入的标准:
finally方法不接受任何参数,故可知它跟Promise的状态无关,不依赖于Promise的执行结果。
4.5Promise.all()
Promise.all方法接受一个数组作为参数,但每个参数必须是一个Promise实例。
Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作都执行完毕后才执行回调。
只要其中一个异步操作返回的状态为rejected那么Promise.all()返回的Promise即为rejected状态,此时第一个被reject的实例的返回值,会传递给Promise.all的回调函数:
4.6Promise.race()
Promise的race方法和all方法类似,都提供了并行执行异步操作的能力,但是all方法的效果实际上是「谁跑的慢,以谁为准执行回调」,而race方法则是「谁跑的快,以谁为准执行回调」,以下就是race的执行过程:
OK,收工!如果可以实现记得点赞分享,谢谢老铁~