async
1. 概念
- 用于声明异步函数,返回值为一个Promise对象。
- 类似以同步的方式来写异步方法。
- 语法:
async function fn() {
console.log('Hello World!');
}
console.log(fn.constructor); // Promise()
// 这里证明其返回值是一个Promise对象
2. 返回值
问题:返回值是一个Promise对象,那么函数本身定义的返回值去哪里了?
答:
- Promise的异步结果时通过
.then()或者.catch()方法来获取并处理的。 - 如果异步函数回调
resolve,则用then()处理;异步回调reject,则用.catch()处理。
// 使用.then()的情况
async function fn1() {
return 'Hello world!';
}
fn1.then(res => {
console.log(res); // Hello world!
})
// 使用.catch()的情况
async function fn2() {
consolelog(a1); // a1未定义,则报错 => 回调reject方法
}
fn2.catch(err => {
console.log(err); // ReferenceError: a1 is not defined
});
// 既有返回值,又有错误处理的时候
async function fn3() {
console.log(a1);
return 'Hello world!';
}
fn3().then(res => {
console.log(res);
}).catch(error => {
console.log(error); // ReferenceError: a1 is not defined
})
// 【注意】只会执行reject状态下的语句
await
1. 概念 - 等待
- 语法:
var value = await myPromise();
- 所谓等待,指暂停当前
async function内部语句的执行,等待使用await声明的语句执行完成并返回结果后,继续执行async funciton函数内部的剩余语句。 myPromise()是一个Promise对象,而自定义的变量value则用于获取Promise对象返回的resolve状态值。
2. 用法
- await必须在
async function内使用,则会提示语法错误。 - 如果
await后面跟其他值,则直接返回该值。
async function fn() {
console.log(1);
var result = await new Promise(function(resolve, reject) {
setTimeout(function(){
resolve(2);
}, 2000);
});
console.log(result);
console.log(3);
console.log(await 4); // 4 会被直接返回
}
fn();
// 1
// 2 (2 秒后输出)
// 3
// 4
3. 返回结果
await会等到后面的Promise返回结果 后才会执行async函数后面剩下的语句。- 也就是说,如果
Promise不返回结果(没有resolve/reject),后面的代码就不会执行。
async function fn() {
console.log(1);
await new Promise(function(resolve, reject) {
setTimeout(function() {
console.log(2);
}, 2000);
});
console.log(3);
}
fn();
// 1
// 2 (2 秒后输出,并且后面不会继续输出 3)
- 如果
await后面的Promise返回一个 reject 状态的结果,则会被当成 错误 抛出。
async function fn() {
console.log(1);
var result = await new Promise(function(resolve, reject) {
setTimeout(function() {
reject(2);
}, 2000);
});
console.log(3);
}
fn();
// 1
// Uncaught (in promise) 2 (2 秒后输出)
// 3没有输出,说明异常抛出后,后面的执行也被忽略
4. 非await部分
- 内部遇到
await会等到返回结果再继续执行下去。 - 非
await部分仍然会以正常的异步/同步方式执行。(如遇到setTimeout()还是会放入任务队列中......)
async function fn() {
console.log(0);
await new Promise(resolve => {
setTimeout(() => {
console.log(1);
resolve();
}, 1000);
});
setTimeout(() => {
console.log(2);
}, 0);
console.log(3);
}
fn();
// 0
// 1(2 秒后)
// 3
// 2
5. await内部
- 函数会等待
await返回结果再继续执行,但await内部的代码依然按正常的同步/异步执行。
async function fn() {
console.log(0);
setTimeout(() => {
console.log(1);
}, 0);
await new Promise(resolve => {
setTimeout(() => {
console.log(2);
}, 0);
console.log(3);
setTimeout(() => {
console.log(4);
resolve();
}, 1000);
setTimeout(() => {
console.log(5);
}, 0);
});
setTimeout(() => {
console.log(6);
}, 0);
console.log(7);
}
fn();
// 0
// 3
// 1
// 2
// 5
// 4(2 秒后)
// 7
// 6