Promise
Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果,并且这个事件提供统一的 API,可供进一步处理。
Promise 对象有以下两个特点:
1、Promise对象的状态不会受到外界操作的影响。Promise有三种状态:Pending、Resolved和 Rejected,下面会具体介绍。只有等异步操作结束,得到操作结果后,由Promise根据结果决定自身是什么状态。
2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 或者从 Pending 变为 Rejected。只要状态改变了,就会一直保持这个状态。
Promise 也有一些缺点:
1、无法取消 Promise,一旦新建它就会立即执行,无法中途取消。
2、如果不设置回调函数,Promise 内部抛出的错误,不会传到外部。
3、当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
Promise的三种状态:
Pending
:进行时,但是无法知道处理进度,只知道目前正在处理这次异步操作;
Resolved
:已完成,又称 Fulfilled,表示异步操作结果正确回调方法;
Rejected
:已失败,表示处理中途抛出异常,或者处理结果不正确回调方法;
简单的使用
new Promise( function(resolve, reject) {...} /* executor */ );//executor(参数)
executor是带有 resolve 和 reject 两个参数的函数 。Promise构造函数执行时立即调用executor 函数, resolve 和 reject 两个函数作为参数传递给executor(executor 函数在Promise构造函数返回所建promise实例对象前被调用)。executor 函数内部通常会执行一些异步操作,一旦异步操作执行完毕(可能成功/失败),要么调用resolve函数来将promise状态改成fulfilled,要么调用reject 函数将promise的状态改为rejected。
示例:
let requestPromiseOK = new Promise((resolve,reject)=>{
//模拟异步耗时操作
let res = {state:'true',code:200}
setTimeout(() => {
//根据返回值,分别调用成功/失败回调
if (res.code == 200) {
resolve(res)
} else {
reject(res)
}
}, 1000);
})
let requestPromiseFail = new Promise((resolve,reject)=>{
let res = {state:'true',code:200}
//模拟失败
res.code = 404
setTimeout(() => {
if (res.code == 200) {
resolve(res)
} else {
reject(res)
}
}, 1000);
})
//第一种异步回调处理
requestPromiseOK.then((data)=>{
//处理resolve回调
console.log(data)
},(error)=>{
//处理reject回调
console.error(error)
})
//第二种异步回调处理(推荐使用)
requestPromiseFail.then((data)=>{
//处理resolve回调
console.log(data)
aNotDefinedVariable//此处使用了一个未定义的变量,会抛出错误(ReferenceError: aNotDefinedVariable is not defined)
}).catch((error)=>{
//处理reject回调或resolve回调处抛出的异常
console.warn(error)
})
Async Await
Async Await结合Promise使用,表达一个异步操作,内部函数体内。awite function()操作为要等待的操作,之后的await操作执行完毕,再执行后面的代码。
async的用法,它作为一个关键字放到函数前面,调用会返回一个promise 对象
async printHello() {
return 'hello'
}
要想获取到async 函数的执行结果,就要调用promise的then 或catch 来给它注册回调函数
async printHello() {
throw Error('some error hanppen')//模拟reject
}
printHello().then((data)=>{
console.log(data)
}).catch((error)=>{
console.log(error)
})
async函数的执行会返回一个promise 对象,并且把内部的值进行promise的封装。如果promise对象通过then或catch方法又注册了回调函数,async函数执行完以后,注册的回调函数就会放到异步队列中,等待执行。如果只是async, 和promise 差不多,但有了await就不一样了, await 关键字只能放到async 函数里面,await是等待的意思,后面可以放任何表达式,不过更多的是放一个返回promise 对象的表达式,它等待的是promise 对象执行完毕,并返回结果
//延时两秒后检查
checkNumIsZeroAfter2Seconds(num) {
return new Promise((resolve,reject)=>{
setTimeout(() => {
if (num == 0) {
resolve(true)
} else {
reject(num + ' does not equal 0')
}
}, 2000);
})
}
async checkNumIsZero(num) {
try {
let result = await this.checkNumIsZeroAfter2Seconds(num)
console.log(result)
} catch (error) {
console.log(error)
}
}
checkNumIsZero(10)//10 does not equal 0
checkNumIsZero(0)//true
解释下以上代码的执行过程,调用checkNumIsZero 函数,遇到了await语句,代码执行就暂停到这里,它等待checkNumIsZeroAfter2Seconds执行完毕,等拿到resolve 的值后,代码继续向下执行输出结果。