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
