Promise基本概念
promise是一个对象,他的定义格式是这样的
new Promise((resolve, reject) => {
})
//后面可以接then或catch
promise有三个状态:{
1、pending-----[待定]初始状态
2、fulfilled----- [实现]操作成功
3、rejected -------[被否决]操作失败
}
resolve和reject分别是用来标记promise实现或否决状态的两个参数
当promise状态发生改变,就会触发then()或catch()的响应函数处理后续步骤,如果标记为resolve,则触发then(),反之则为catch()
promise状态一经改变,不会再变。
Promise对象的状态改变,只有两种可能:
从pending变为fulfilled
从pending变为rejected。
这两种情况只要发生,状态就凝固了,不会再变了。
实践是检验真理的唯一标准
demo
demo()
function demo() {
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('已过两秒')
}, 2000);
}).then(res => {
console.log('res: ', res)
})
}
运行结果:两秒后输出res
这说明then方法可以获取到resolve()标记的内容并且使用
换成reject试试:
demo()
function demo() {
new Promise((resolve, reject) => {
setTimeout(() => {
reject('已过两秒')
}, 2000);
}).then(res => {
console.log('res: ', res)
}).catch(err => {
console.log('err: ', err)
})
}
可以看到,then中的语句没有执行,而是直接跳到了catch
demo2
demo2()
function demo2() {
new Promise((resolve, reject) => {
resolve('标记为resolve')
reject('标记为reject')
console.log('如果输出这一句话,说明resolve和reject后的语句还可以执行')
}).then(res => {
console.log('第一次then: ', res)
return '第一次then的return值'
}).then(res => {
console.log('第二次then:', res)
}).catch(err => {
console.log('catch: ', err)
})
}
运行结果:
结果说明了三件事:
resolve和reject只是标记promise的状态,并不会直接开始执行then或者catch里的语句
promise状态被标记后就不会更改,因为catch并没有执行
then()中return的值可以被下一次then()调用
async和await的基本概念
async是asynchronous(翻译结果为:异步的) 的缩写
await是async wait的缩写,也就是 异步等待
async是函数的声明,用于声明函数是异步函数,并不是说想要把一个函数变为异步的就一定需要async
这个声明只是为了await的使用
await 用于等待一个表达式或函数的执行完成,在完成前不允许执行之后的语句,并且只能在有async声明的函数中使用
也就是说如果一个函数声明了async,但是没有在这个函数中使用await,则这个声明没有意义,原来是怎么样就还是怎么样
实践
demo3
testDemo3()
function demo3() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ok')
console.log('三秒已过')
}, 3000);
})
}
async function testDemo3() {
console.log(demo3())
console.log(await demo3())
console.log('看看这一句话出来要多久:')
}
运行结果
运行后马上输出:
三秒后继续输出:
来分析一下:
开始执行第一次log时,由于没有用await标记,是立刻输出demo3()的,并且开始执行demo3()里面的语句,而demo3() return了一个promise对象,所以会输出Promise{ <pending> },pending表示这一时刻的promise对象还是初始状态,三秒后,demo3()执行完成,输出‘三秒已过’(先输出再执行,执行用了三秒)
第二次log是紧接着第一次log的,并且用await标记了demo3(),所以当demo3()执行完成时,也就是3秒后,才执行log。(没等第一次demo3执行完就开始了,并且第二次demo3与第一次间隔甚短)所以两个‘三秒已过’几乎是同时出现。然后还发现用await标记了的demo3会返回他的resolve值
第三次log也是三秒后出来的,这说明他被第二次log中的await阻塞了
将testDemo3改一改,demo3原封不动:
testDemo3()
function demo3() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ok')
console.log('三秒已过')
}, 3000);
})
}
async function testDemo3() {
let x = await demo3()
console.log('x: ', x)
}
运行结果
demo4
demo4()
async function demo4() {
let pro = new Promise(resolve => {
setTimeout(() => {
console.log('五秒已过')
resolve('ok')
}, 5000);
})
console.log('pro: ', pro)
await pro
console.log('pro: ', pro)
}
运行结果