promise
JavaScript是单线程
因为js语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。
异步任务
但这样很容易造成阻塞,所以把任务分成了同步任务和异步任务两种,异步模式可以同时执行多个异步任务,当主线程遇到异步任务,就把异步任务放进’任务队列’里,执行完同步任务后,再循环的去检查任务队列里面有哪些异步任务要执行,
回调函数
在没有promise前,使用的是回调函数的方式来执行异步任务,就是当主线程开始执行这个异步任务时,就去执行这个异步任务对应的回调函数。
异步任务比如:ajax请求、定时器、事件函数等
回调地狱
但是不同的异步任务耗时不一,我们没有办法控制不同的异步任务的前后顺序,当一个异步任务需要依赖另一个异步任务的结果时,如果不控制这两个异步任务的先后顺序,就很容易会报错:
以向后端发送请求数据为例来说,一个请求b需要在拿到请求a中返回的参数后,才能正确发起请求,这种时候的解决方案是:在请求a的回调函数里去发起b请求,那如果这样的先后依赖多了的话,一层套一层,就会出现回调地狱的问题,代码不易读,耦合度过高,后期亦不好维护。
请求1(function(请求结果1){
请求2(function(请求结果2){
请求3(function(请求结果3){
请求4(function(请求结果4){
请求5(function(请求结果5){
请求6(function(请求结果6){
...
})
})
})
})
})
})
promise
那为了解决回调地狱的问题,ES6就新增了Promise,是异步编程的一种解决方案,有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数
promise的2个参数(resolve,reject) 和 3个状态(pending ,fulfilled/resolved,rejected)
Promise是一个构造函数,使用new Promise()得到一个实例,new Promise()需要传进去一个函数,这个函数有2个参数:
-
一个是resolve回调函数,在异步操作成功时调用,把promise的状态从pending转变到fulfilled(又称resolved),并将异步操作的结果,作为参数传递出去
-
一个是reject回调函数,在异步操作失败时调用,把Promise的状态从从 pending 变为 rejected,并将异步操作报出的错误,作为参数传递出去
// 创造一个Promise实例
const promise = new Promise((resolve, reject) => {
// ... some code
if (/* 异步操作成功 */){
resolve(value); // value是异步请求成功的结果,resolve把value传出去
} else {
reject(error); // error是异步请求报的错误,reject把error传出去
}
});
Promise.prototype.then()
Promise实例生成后,当promise状态一改变,不管是成功还是失败,就都会来到promise对象的then方法,.then()根据其最终状态,选择特定的状态响应函数执行
then方法可以接受两个回调函数作为参数:
-
第一个回调函数是promise对象的状态变为resolved的时候调用,
-
第二个回调函数是promise对象的状态变为rejected时调用。(其中第二个函数是可选的,不一定需要提供)
这两个函数都接受Promise对象传出的值【resolve(value) / reject(error) 】value或者error作为参数,
【then中的函数一定要return一个结果或者一个新的Promise对象(新的异步任务,才可以让之后的then回调接收】
// 创造一个Promise实例
const promise = new Promise((resolve, reject) => {
// ... some code
if (/* 异步操作成功 */){
resolve(value); // value是异步请求成功的结果
} else {
reject(error); // error是异步请求报的错误
}
});
promise.then(
value => {
// value是异步请求成功的结果
// 对请求来的结果进行处理,然后返回一个结果或者一个新的Promise对象,才可以让之后的then回调接收
return value;
},
error => {
// error是异步请求报的错误
// 对错误进行处理
console.log(error);
}
)
then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)因此可以采用链式写法,即then方法后面再调用另一个then方法。
new Promise(请求1)
.then(请求2(请求结果1))
.then(请求3(请求结果2))
.then(请求4(请求结果3))
.then(请求5(请求结果4))
.catch(处理异常(异常信息))
Promise.prototype.catch()
Promise.prototype.catch方法是.then(null, rejection)
的别名,如果Promise的状态变为reject时,会被catch捕捉到。
Promise
对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止
一般来说,使用catch
方法代替then()
的第二个参数
所以就把成功的处理逻辑写在.then()里,把失败的处理逻辑写在.cache()里
const sayhello = (order) => {
return new Promise