async
async
函数是 Generator
函数的语法糖(说白了就是更好用些)
async
函数,就是将 Generator
函数的星号 *
替换成 async
,将 yield
替换成 await
,仅此而已
async function show() { // async 表示这个函数里面有异步的任务 await '33'; // await 表示后面的结果需要等待,然后再处理 }; let p1 = show();
async
& Generator
Generator
函数的执行必须靠执行器,而 async
函数自带执行器。就是说,Generator
函数需要手动地调用 next()
;而 async
函数的执行,与普通函数一样async
和 await
,比起 *
和 yield
,语义更清楚。async
表示函数里有异步操作,await
表示后面的表达式需要等待结果await
命令后面是一个 Promise
对象。如果不是,会转成一个立即 resolve
的 Promise
对象Promise
:这比 Generator
函数的返回值是 Iterator
对象方便;可以用 then
方法指定下一步的操作async
函数可以看作是多个异步操作,包装成的一个 Promise
对象。而 await
就是内部 then
命令的语法糖
async
的使用await
只能放到 async
函数中使用async
函数的返回值:一个 Promise
对象async function show() { await '33'; return 1; }; let p1 = show(); console.log(p1); // Promise {<pending>} p1.then(res => { console.log(res); // 1 });
await
语句后面的 Promise
的状态变成 reject
,整个 async
函数会中断async function fn() { await Promise.reject('出错了'); console.log(1); // 不会被执行 }; fn().then(null, err => { console.log(err); // 出错了 });
await
后面的语句出错,函数将中断,后面的语句将不会被执行async function fn() { throw new Error('出错了'); console.log(1); // 不会被执行 }; fn().catch(err => { console.log(err); // Error: 出错了 });
1. 使用
try{} catch(){}
async function fn() { try { await Promise.reject('出错了'); } catch (e) { let a = await Promise.resolve("成功了"); console.log(a); }; };
2. 添加
catch
捕获错误
本来 await
后面的就是 Promise
对象,我们就可以直接使用 catch
处理
async function fn() { await Promise.reject('出错了').catch( err => { console.log(err); } ); let a = await Promise.resolve("成功了"); console.log(a); };
3. 统一捕获错误
个人建议,只要有 await
的地方都 try catch
掉,然后统一处理结果
async function fn() { try { let f1 = await Promise.resolve('成功了'); let f2 = await Promise.resolve('成功了'); let f3 = await Promise.reject('出错了'); } catch (e) { console.log(e); }; };
4. 也可以用
Promise.all()
方法
如果你多次请求的数据之间没有关联,就可以使用 Promise.all()
async function fn() { let [f1, f2, f3] = await Promise.all([ Promise.resolve('成功了1'), Promise.resolve('成功了2'), Promise.resolve('成功了3') ]); console.log(f1); console.log(f2); console.log(f3); }; fn(); // 成功了1 成功了2 成功了3
ajax 请求
function ajax(url) { return new Promise((resolve, reject) => { $.ajax({ url, type: 'get', success: resolve, error: reject }); }); }; async function show() { try { let result = await ajax(`https://jsonplacehouger.typicode.com/todos/1'`); let result2 = await ajax(`https://jsonplacehouger.typicode.com/todos/2`); let result3 = await ajax(`https://jsonplacehouger.typicode.com/todos/3`); } catch (error) { console.log('error', error); } };
generator
只是一个过渡期,建议大家用 async