romise的基本使用
Promise是承诺的意思,es6中提出一个新api。
用来优化异步代码。它的经典使用方式如下
var p1 = new Promise(function(resolve,reject){
//异步操作 resolve(obj1) 或者 reject(obj2)
});
p1.then(function(rs){
// 如果p1的状态是resolved,则then中的函数
//会执行,且obj1的值会传给rs
}).catch(function(rs){
// 如果p1的状态是reject,则catch中的函数
// 会执行,且obj2的值会传给rs
}).finally(function(){
// 一定会执行的函数
})
三种状态和值
一个Promise对象的状态可能是如下三种之一:pending,resolved,rejected 。下面分别介绍。
初始态pending
- pending。它的意思是 "待定的,将发生的",相当于是一个初始状态。 创建Promise对象时,且没有调用resolve或者是reject方法,相当于是初始状态。这个初始状态会随着你调用resolve,或者是reject函数而切换到另一种状态。
var p = new Promise((resolve,rejectok,err)=>{ console.info('发呆.....' )})
console.dir(p)
成功态resolved
- 也有叫fulfilled的,resolved。表示解决了,就是说这个承诺实现了。 要实现从pending到resolved的转变,需要在 创建Promise对象时,在函数体中调用了resolve方法(即第一个参数)。
var p = new Promise((resolve,reject)=>{ resolved();})
console.dir(p)
失败态rejected
- rejected。拒绝,失败。表示这个承诺没有做到,失败了。要实现从pending到rejected的转换,只需要在创建Promise对象时,调用reject函数。
var p = new Promise((resolve,reject)=>{ reject()} )
console.dir(p)
三种状态小结
- 状态是可转化。
最初创建promise对象时,默认状态是pending,如果在函数体内部调用了第一个参数对应的函数,则状态变成了resolved;如果调用了第二个参数对应的函数,则状态变成了rejected。
pending ----- resolve() --> resolved;
pending ----- reject() --> rejected;
- 状态转换是不可逆的。
一旦从pending ---> resolved(或者是rejected),就不可能再回到pending,也不能由resolved变成rejected。
使用promise改造回调函数
下面我们回到具体的问题:如何用promise解决回调地狱
async,await 是es7中新增的语法,用来进一步改进异步代码的写法,是promise升级版!
async
async函数返回一个 Promise 对象。
async函数内部return语句返回的值是Promise 对象的值
function f1 () {
return 1
}
async function f2 () {
return 1
}
async function f3 () {}
const r1 = f1()
const r2 = f2()
const r3 = f3()
console.log(r1) // 1
console.log(r2) // Promise, resolved(1)
console.log(r3) // Promise, resolved(undefined)
r2.then(res => { console.log(res) })
r3.then(res => { console.log(res) })
await 命令
await的外层函数必须有一个async.
正常情况下,await命令后面是一个 Promise 对象,返回该promise的值。如果不是 Promise 对象,就直接返回对应的值。
解决回调地狱
async function fnAxios() {
const res = await axios.get('http://localhost:3000/get)
console.log('第一次请求', res);
const res1 = await axios.get('http://localhost:3000/getaxios)
console.log('第二次请求', res1);
const res2 = await axios.get('http://localhost:3000/getav)
console.log('第三次请求', res2);
}
fnAxios()
一环套一环的ajax请求可以直接这样写,一直套下去都是按照顺序执行.
我的表达能力不太行,想深入了解还是建议去blbl上面找视频看下,视频讲解肯定比纯文字要好的多