async异步函数的声明
- async定义异步函数(
async function someName(){...})
async异步函数的执行流程
- async异步函数在没有await时其执行流程和普通函数执行流程一样,
async异步函数和普通函数的区别
- 区别一:返回值的区别;async异步函数的返回值一定是一个Promise
async function foo() {
console.log("foo function start~")
console.log("中间代码~")
console.log("foo function end~")
// 1.返回一个值
// 2.返回thenable
// return {
// then: function(resolve, reject) {
// resolve("hahahah")
// }
// }
// 3.返回Promise
return new Promise((resolve, reject) => {
setTimeout(() => {
// resolve("hehehehe")
reject(999)
}, 2000)
})
}
// 异步函数的返回值一定是一个Promise
foo().then(res => {
console.log("promise then function exec:", res)
}).catch(err => {
console.log('err:' + err); // err:999
})
- 情况一:异步函数也可以有返回值,但是异步函数的返回值会被包裹到Promise.resolve中;
- 情况二:如果我们的异步函数的返回值是Promise,Promise.resolve的状态会由Promise决定;
- 情况三:如果我们的异步函数的返回值是一个对象并且实现了thenable,那么会由对象的then方法来决定;
- 区别二:函数的异常处理:如果是普通函数代码中出现异常错误后,后续代码不会再被执行,但是当async异步函数抛出错误后,会被.catch()方法捕获,函数后续代码不会受影响。
async function foo() {
console.log("foo function start~")
console.log("中间代码~")
// 异步函数中的异常, 会被作为异步函数返回的Promise的reject值的
throw new Error("error message")
console.log("foo function end~") // 此行代码不管在啥时候都不会执行
}
// 异步函数的返回值一定是一个Promise
foo().catch(err => {
console.log("err:", err)
})
console.log("后续还有代码~~~~~") // 此行代码在异步函数中正常执行
// foo function start~
// 中间代码~
// 后续还有代码~~~~~
// err: Error: error message
await关键字
- async函数另外一个特殊之处就是可以在它内部使用await关键字,而普通函数中是不可以的。也就是说await必须在async异步函数中使用。
- 如果await后面是一个普通的值,那么会直接返回这个值;
function resolveAfter2Seconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}
async function f1() {
let x = await resolveAfter2Seconds(10);
console.log(x); // 10
return 999
}
f1().then((res) => {
console.log(res); // 999
})
- 通常使用await是后面会跟上一个表达式,这个表达式会返回一个Promise; 那么await会等到Promise的状态变成fulfilled状态,之后继续执行异步函数; (await等待的是调用requestData()-resolve的结果,等待成功的结果,在await后面的代码相当于在.then方法里面的代码)
function requestData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(222)
// reject(1111)
}, 2000);
})
}
async function foo() {
const res1 = await requestData() // 此行以后的代码相当于.then方法里面代码
console.log("后面的代码1", res1) // 后面的代码1 222
}
function requestData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(222)
// reject(1111)
}, 2000);
})
}
async function foo() {
const res1 = await requestData().then(res => {
console.log(res); // 222
})
console.log("后面的代码1", res1) // 后面的代码1 undefined
}
- 如果await后面的表达式,返回的Promise是reject的状态,那么会将这个reject结果直接作为函数的Promise的 reject值;
function requestData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
// resolve(222)
reject(1111)
}, 2000);
})
}
async function foo() {
const res1 = await requestData()
}
foo().catch(err => {
console.log("err:", err) // err: 1111
})
- 如果await后面是一个thenable的对象,那么会根据对象的then方法调用来决定后续的值;
async function foo() {
const res1 = await {
then: function(resolve, reject) {
// resolve("abc")
reject('cba')
}
}
console.log(33333); // 后面两行都没结果
console.log("res1:", res1) // res1: abc
return 222
}
foo().then(res => {
console.log(res)
}).catch(err => {
console.log("err:", err) // err: cba
})
async函数本身会return一个promise,如果await后面表达式返回一个普通值或者promise是fulfilled状态那么都会打印结果,但是如果是rejected状态那么后续就不会再打印