它是一个ES6提出一个新语法,用来优化异步代码的写法
promise:承诺。
- 生活中.它是用来表述
对将来要发生的事情的肯定
- 一个Promise对象的状态可能是如下三种之一:
pending
,resolved
,rejected
- 初始
pending
- 成功
resolve
- 失败
reject
promise的兑现
在构造器的函数体中,一旦状态发生了变化,就会进行then,或者是catch中去,同时把promiseValue传入对应的函数
根据实际情况的需要,也可以不加上finally()。
finally()是不论成功与否都会进行的一步
then的格式
下面从其调用格式,执行逻辑及返回值三个方面来介绍
它可以写两个参数,如下:
// p 是一个promise对象
p.then(函数1[,函数2])
它的两个参数都是函数。
- 第一个参数是resolved状态的回调函数。当p的状态从pending变成了resolved之后,函数1会执行。
- 第二个参数是rejected状态的回调函数。 当p的状态从pending变成了rejected之后,函数2会执行。
- 其中第二个参数是可选的,如果只写一个参数的话就是如下:
promise对象.then(函数1)
它的两个参数都是函数,其执行逻辑是:↓
- 如果promise对象的状态是resolved,则then()会执行第一个函数,并传入当前的PromiseValue(即上面的val1);
- 如果promise对象的状态是rejected,则then()会执行第二个函数,并传入当前的PromiseValue(即上面的val2);
- 特别地,如果promise对象的状态是rejected,且此时then方法并没有设置第二个参数,就会向外抛出一个错误,错误的提示大约是
Uncaught (in promise)
。
var p = new Promise((resolve,reject)=>{
resolve(val1);
// or reject(val2)
})
p.then((okVal)=>{
console.info("成功");
console.log(okValue);
}, (errVal)=>{
console.info("失败");
console.log(errValue);
})
then的返回值(难点)
then()方法的返回值也是一个promise对象,所以它支持链式写法。但是要注意的是它的返回值是一个新的promise对象,与调用then方法的并不是同一个对象
var p1 = new Promise(()=>{});
var p2 = p1.then(function f_ok(){}, function f_err(){});
// p2也是一个promise对象。
console.log(p1 === p2); // false
如上代码可以说明p1.then()的结果是一个与p1不同的promise对象。换句话说,then()会封装一个全新的promise对象p2。那既然 p2也是一个promise对象,那么,p2的状态(promiseStatus)和值(promiseValue)分别是什么?
p2的状态及promiseValue按如下规则来确定
- 如果p1的状态是pending,则p2的状态也是pending。
- 如果p1的状态是resolved,then()会去执行f_ok,则p2的状态由f_ok的返回值决定。
- 如果f_ok返回值不是promise对象,则p2的状态是resolved,且p2的promiseValue就是f_ok函数的return值。
- 如果f_ok返回值是一个promise对象,则p2的状态及promiseValue以这个promise对象为准。
- 如果f_ok这个函数内部发生了错误(或者是用户主动抛出错误),则p2的状态是rejected,且p2的promiseValue就是这个错误对象。
- 如果p1的状态是rejected,then()会去执行f_err,则p2的状态由f_err的返回值决定。
- 如果f_err返回值不是promise对象,则p2的状态是resolved,且p2的promiseValue就是f_err函数的return值。
- 如果f_err返回值是一个promise对象,则p2的状态及promiseValue以这个promise对象为准。
- 如果f_err这个函数内部发生了错误(或者是用户主动抛出错误),则p2的状态是rejected,且p2的promiseValue就是这个错误对象。
async语法
async,await 是es7中新增的语法,用来进一步改进异步代码的写法,是promise升级版!
async
函数返回一个 Promise 对象,可以使用then
方法添加回调函数。
async
函数返回一个 Promise 对象。
async
函数内部return
语句返回的值是Promise 对象的值
await 命令
正常情况下,await
命令后面是一个 Promise 对象,返回该promise的值。如果不是 Promise 对象,就直接返回对应的值。 await 需要和async语法一起使用
async的返回值
async
函数返回的 Promise 对象,必须等到内部所有await
命令后面的 Promise 对象执行完,才会发生状态改变,除非遇到return
语句或者抛出错误。也就是说,只有async
函数内部的异步操作执行完,才会执行then
方法指定的回调函数。
const p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve(100), 3000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => resolve(200), 5000)
})
async function f () {
console.log('开始执行f')
var a = await p1
console.log('p1完成了')
var b = await p2
console.log('p2完成了')
return a + b
}
console.log('主函数运行...')
const res = f()
console.log('f()完成,返回值是', res)
res.then(res => { console.log(res) })
主函数运行...
开始执行f
f()完成,返回值是 Promise { <pending> }
----此处等了3s----
p1完成了
----此处等了2s----
p2完成了
300