一、Async-await原理
1、原理1
async函数返回一个 Promise 对象,可以使用then方法添加回调函数
。举例说明:
// async返回的是Promise对象?
async function testAsync() {
return 'hello';//上篇文章Promise对象的返回值如果不是Promise,会通过Promise.resolve()转化为Promise,再进行处理
}
const result = testAsync()
console.log(result);//Promise { 'hello' } 说明async返回的是Promise对象
await 命令后面的Promise对象,默认状态是resolved的,运行结果可能是 rejected,此时等同于 async 函数返回的 Promise 对象被reject。当async函数内部抛出错误的时候,会导致返回的 Promise 对象变为reject状态
。抛出的错误对象会被.then()方法的第二个回调函数接收或者.catch()方法回调函数接收到。因此需要加上错误处理,可以给每个 await 后的 Promise 增加 catch 方法;也可以将 await 的代码放在 try…catch 中。
async function testAsync() {
// await await等待还是promise对象
return 'hello'
}
testAsync()
.then((result)=>{
console.log(result);
})
.catch((error)=>{
console.log(error);
})
// hello 返回的是resolve状态的结果
2、原理2
await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。代码说明:
// await
async function getName(){
// return 'hello';
return await 'hello';//上面直接return等价于这个return
}
getName()
.then(result=>{console.log(result);})
3、原理3
await的使用,必须要有async
。async返回的是一个Promise对象,await等待的就是这个Promise对象,所以await不能没有async(但是async可以没有await)。如果await没有async会报错:
// await没有async会报错
function testAwait(){
return await 'letting go'
}
testAwait()
.catch(error=>{
console.log(error);
})
//SyntaxError: await is only valid in async function
二、Async-await规则
1、async封装Promise
// async封装Promise
async function fn1() {
return 'the lonely revelry';// //相当于return Promise.resolve('the lonely revelry')
const data = await fn1();//接收data值
}
fn1()//执行async函数,返回的是一个Promise对象
.then(data => {
console.log('content =', data)
})
//content = the lonely revelry
2、await相当于then
// await---.then()
async function getName(){
const operate=Promise.resolve('mochoc')//执行函数
const name= await operate //await相当于Promise的then operate.then(name=>{})
console.log('name:',name)
}
getName();
( async function(){
const person=await 'rainbow' //await Promise.resolve('rainbow') await后面不跟Promise,也会被封装成Promise
console.log('person:',person)//400
})();//自执行函数
//name: mochoc
//person: rainbow
3、多个await时,按时序执行
当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行
。
async function testOrder() {
await Promise.reject('出错了')//UnhandledPromiseRejectionWarning: 出错了
await Promise.resolve('hello world'); // 不会执行
}
testOrder();
4、try…catch相当于catch
如果希望即使前一个异步操作失败,也不要中断后面的异步操作。可将第一个await放在try...catch结构里面
,这样不管这个异步操作是否成功,第二个await都会执行。
// try...catch
!(async function () {
const testError = Promise.reject('error')//rejected状态
// const testError=throw new Error('error');
try {
const result = await testError; //await相当于then,但是reject不会触发then
console.log('success:'+result) //不会输出,因为const result = await testError被报错,被catch捕获
} catch (error) {
console.error('error:'+error)//try...catch 相当于Promise的catch
}
})()
//error: error
当await后面是Promise对象的时候,我们也可直接在await后面直接.catch捕获
错误:
async function testError() {
await Promise.reject('出错了')
.catch(error => console.log(error));//这里捕获错误,不会影响下一个await执行
return await Promise.resolve('hello world');
}
testError()
.then(result => console.log(result))
注意:
(1)await不能单独出现,其函数前面一定要有async。
(2)await会干两件事:
第一,将写在await后面的代码放到async创建的那个Promise里面执行。
第二、将写在await下面的代码放到前一个创建的那个Promise对象的.then里面执行。
(3)await返回的也是Promise对象,他只是把await下面的代码放到了await返回的promise的.then里面执行。