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