Promise的理解和运用
Promise是什么
理解
Promise是ES6标准化提供的一套异步编程的解决方案,用来替代传统回调函数的异步操作。Promise在JavaScript中是一个内置的类,它的每一个对象都可以负责一个异步操作。
抽象表达
Promise
是js
中进行异步编程的新的解决方案(旧的是纯回调函数 )具体表达
- 从语法上来说:Promise是一个构造函数
- 功能上来说:Promise对象用来封装一个异步操作并获取其结果
Promise的状态改变
- pending: 初始状态, 非 fulfilled 或 rejected.
- fulfilled: 成功的操作.
- rejected: 失败的操作.
这里从pending状态可以切换到fulfill状态(jQuery中是resolve状态),也可以从pengding切换到reject状态,这个状态切换不可逆,且fulfilled和reject两个状态之间是不能互相切换的。
Promise基本流程
基本使用
let a = new Promise((resolve,reject)=>{
// 异步操作代码
if(异步操作成功){
resolve(数据);
}else{
reject(数据);
}
});
a.then(function(data){
//即指定resolve函数,
}).catch(function(err){
//即指定reject函数,
});
//封装ajax请求获取数据
function ajax(url,arr){
return new Promise(function(resolve,reson){
$.ajax({
url:url,
success:function(data){
if(arr==undefined){
resolve([data]);
}else {
//...arr不定长参数
resolve([data,...arr]);
}
},
fail:function(err){
reson(err);
}
});
});
}
// 指定then和catch
let p = ajax("https://www.fastmock.site/mock/bb4157f45a0b5ffdcb3f6d984517a6c0/woniuMovie/getMoviesCount");
p.then(function(data){
return ajax('https://www.fastmock.site/mock/bb4157f45a0b5ffdcb3f6d984517a6c0/woniuMovie/getAllMovies',data) ;
}).then(function(data1){
return ajax('https://www.fastmock.site/mock/bb4157f45a0b5ffdcb3f6d984517a6c0/woniuMovie/getAllTypes',data1);
}).then(function(data2){
console.log(data2);//输出所有请求的数据
})
- 当promise对象创建后,会立即执行异步操作。对于异步操作成功后要执行的
resolve
函数或失败后要执行的reject
是由then和catch来补充的- 会根据异步操作的结果调用对应的函数。如果异步操作执行成功,会执行then里的函数,如果失败,会执行catch里的函数。
- promise对象执行异步 操作后会保存结果。直到我们指定了then和catch后才会拿到异步的结果并处理。then指定的是resolve函数,catch是reject函数
为什么要用Promise
指定回调函数的方式更加灵活
- 旧的:必须在启动异步任务前指定
- promise:启动异步任务 => 返回 promise 对象 => 给 promise 对象绑定回调函数 (甚至可以在异步任务结束后指定)
支持链式调用,可以解决回调地狱问题
什么是回调地狱?
回调函数嵌套调用, 外部回调函数异步执行的结果是嵌套的回调执行的条件
回调地狱的缺点?
不便于阅读 不便于异常处理
解决方案?
promise 链式调用
终极解决方案?
async/await
如何使用Promise
Promise 构造函数:
Promise (excutor) {} excutor
函数: 同步执行 (resolve, reject) => {}resolve
函数: 内部定义成功时我们调用的函数 value => {}reject
函数: 内部定义失败时我们调用的函数 reason => {}说明: excutor 会在 Promise 内部立即同步回调,异步操作在执行器中执行
Promise.prototype.then
方法: (onResolved, onRejected) => {}onResolved
函数: 成功的回调函数 (value) => {}onRejected
函数: 失败的回调函数 (reason) => {}说明: 指定用于得到成功 value 的成功回调和用于得到失败 reason 的失败回调 返回一个新的 promise 对象
Promise.prototype.catch
方法: (onRejected) => {}onRejected
函数: 失败的回调函数 (reason) => {}说明: then()的语法糖, 相当于:
then(undefined, onRejected)
Promise.resolve
方法: (value) => {}value
: 成功的数据或 promise 对象说明: 返回一个成功/失败的 promise 对象
Promise.reject
方法: (reason) => {}reason
: 失败的原因说明: 返回一个失败的 promise 对象
Promise.all
方法: (promises) => {}promises: 包含 n 个 promise 的数组
说明: 返回一个新的 promise, 只有所有的 promise 都成功才成功, 只要有一 个失败了就直接失败
Promise.race
方法: (promises) => {}promises: 包含 n 个 promise 的数组
说明: 返回一个新的 promise, 第一个完成的 promise 的结果状态就是最终的 结果状态
async与await
- ES7 的新增的内容,作为异步编程的最终解决方案。
- async作为一个函数的修饰符,表示该函数主要用于解决异步编程问题。即该函数里一般情况下主要执行异步代码。
- await作为一个修饰符。只能够在
async
函数中使用。表示等待一个异步操作结束并接收异步操作的处理结果。但需保证该异步操作是用promise来处理的
async函数
- 函数的返回值为 promise 对象
- promise 对象的结果由 async 函数执行的返回值决定
await表达式
await
右侧的表达式一般为promise
对象, 但也可以是其它的值- 如果表达式是
promise
对象,await
返回的是promise
成功的值 - 如果表达式是其它值, 直接将此值作为
await
的返回值
await
必须写在async
函数中, 但async
函数中可以没有await
- 如果
await
的promise
失败了, 就会抛出异常, 需要通过try...catch
捕获处理
async function(){
let a= await promise对象;
}
//能够让多个异步操作像同步代码一样顺序执行并拿到异步操作的数据