async基础语法
async函数返回一个Promise对象,可以使用then方法添加回调函数,当函数执行的时候,遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。async函数返回的是promise对象,可以作为await的参数
//定义一个异步函数·
async function testAsync(){
return 'hello' ;
}
const result=testAsync();
console.log(result);//Promise{<resolved>: "hello async"}
async函数实质上是generator函数(生成器函数)的语法糖
语法糖:指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用
async的重点是错误处理机制
- async函数返回一个promise对象
- async函数内部return语句返回的值,会是then方法回掉函数的参数
async function f(){
return 'hello world';
}
f().then(v=>console.log(v))
//"hello world"
- async函数内部抛出错误,会导致返回的promise对象变为reject状态,抛出的错误对象会被catch方法回调函数接收到
async function f(){
throw new Error("出错了");
}
f().then(
v=>console.log(v),
e=>console.log(e)
)
//Error:出错了
- async函数返回的Promise对象,必须在内部所有的await命令后面的Promise对象执行完,才会发生状态改变,当遇到return语句或者抛出错误.即只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。
//函数getTitle内部有三个操作:抓取网页、取出文本、匹配页面标题。只有这三个操作全部完成,才会执行then方法里面的console.log。
async function getTitle(url) {
let response = await fetch(url);
let html = await response.text();
return html.match(/<title>([\s\S]+)<\/title>/i)[1];
}
getTitle('https://tc39.github.io/ecma262/').then(console.log)
//// "ECMAScript 2017 Language Specification"
async的使用形式
//函数声明
async function foo(){}
//函数表达式
const foo=async function(){}
//对象的方法
let obj={async foo(){}}
obj.foo().then(...)
//class的方法
class Storage {
constructor() {
this.cachePromise = caches.open('avatars');
}
async getAvatar(name) {
const cache = await this.cachePromise;
return cache.match(`/avatars/${name}.jpg`);
}
}
const storage = new Storage();
storage.getAvatar('jake').then(…);
// 箭头函数
const foo = async () => {};
await语法
await命令后是接着一个Promise对象,如不是的话,会被转换为一个立即resolve的Promise对象
async function f(){
return await 123;//123会被转换为Promise对象,并立即resolve
}
f().then(v=>console.log(v))//await命令后面的Promise对象如果变成reject状态,则reject的参数会被catch方法的回调函数接收到
async function f(){
await Promise.reject('出错了');
}
f().then(v=>console.log(v)).catch(e=>console.log(e))//出错了
//上面代码中,await语句前面没有return,但是reject方法的参数依然传入了catch方法的回调函数。这里如果在await前面加上return,效果是一样的。
只要一个await语句后面的 Promise 变为reject,那么整个async函数都会中断执行。
//前一个异步操作失败,也不要中断后面的异步操作。这时可以将第一个await放在try...catch结构里面,
这样不管这个异步操作是否成功,第二个await都会执行
async function f() {
await Promise.reject('出错了');
await Promise.resolve('hello world'); // 不会执行
}//第二个await语句是不会执行的,因为第一个await语句状态变成了reject。
async function f() {
try {
await Promise.reject('出错了');
} catch(e) {
}
return await Promise.resolve('hello world');
}
f().then(v => console.log(v))
// hello world
//还可以在await后面的Promise对象再跟一个catch方法,处理前面的错误
async function f(){
await Promise.reject('出错了').catch(e=>console.log(e));
return await Promise.resolve('hello');
}
f)_.then(v=>console.log(v))
//出错了
//hello