异步函数 async function
async关键字用于声明一个异步函数:
- async是asynchronous单词的缩写,异步、非同步
- sync是synchronous单词的缩写,同步、同时 异步函数有很多种写法
async function foo(){
}
const foo2 = async () => {
}
class Foo{
async bar(){
}
}
异步函数的内部代码执行过程和普通的函数是一致的,默认情况下也是会被同步执行。
//这种和普通函数一点区别都没有
async function foo(){
console.log('foo function start');
console.log('内部代码执行1');
console.log('内部代码执行2');
console.log('内部代码执行3');
console.log('foo function end');
}
console.log("script start");
foo()
console.log("script end");
只有当异步函数有返回值时,和普通函数会有区别
- 异步函数也可以有返回值,但是异步函数的返回值会被包裹到Promise.resolve中
- 如果我们的异步函数的返回值是Promise,Promise.resolve的状态会由Promise决定如果我们的异步函数的返回值是一个对象并且实现了thenable,那么会由对象的then方法来决定
- 如果我们的异步函数的返回值是一个对象并且实现了thenable,那么会由对象的then方法来决
异步函数与普通函数的区别一 返回值
首先我们要明确一点,调用异步函数时会返回一个promise。
async function f(){
return 123
}
const promise = f()
我们可以通过异步函数的返回值来调用promise的then方法。
- 如果什么都不返回 这种情况就类似我们在函数中return undefined
async function foo(){
console.log('foo function start ~');
console.log('中间代码');
console.log('foo function end ~');
// return undefined
}
const promise = foo()
promise.then(res => {
console.log('promise then function exec',res); //promise then function exec undefined
})
- 返回一个普通的值
async function foo(){
console.log('foo function start ~');
console.log('中间代码');
console.log('foo function end ~');
return 123
}
const promise = foo()
promise.then(res => {
console.log('promise then function exec',res); //promise then function exec 123
})
- 返回thenable
async function foo(){
console.log('foo function start ~');
console.log('中间代码');
console.log('foo function end ~');
return {
then(resolve,reject){
resolve("hahahah")
}
}
}
const promise = foo()
promise.then(res => {
console.log('promise then function exec',res); //promise then function exec hahahah
})
- 返回promise
async function foo(){
console.log('foo function start ~');
console.log('中间代码');
console.log('foo function end ~');
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve("hahhaha")
}, 1000);
})
}
const promise = foo()
promise.then(res => {
console.log('promise then function exec',res); //promise then function exec hahhaha
})
和普通函数的区别之捕获异常
普通函数
function foo(){
console.log('foo function start');
throw new Error("有错误")
}
foo()
console.log('后续还有代码'); //程序直接崩溃了
如果是异步函数
async function foo(){
console.log('foo function start');
//异步函数的异常,会被违异步函数返回的Promise的reject值
throw new Error("有错误")
}
foo().catch(err => {
console.log('错误是:',err);
})
console.log('后续还有代码'); //这里还会执行
使用await关键字
async函数另外一个特殊之处就是可以在它内部使用await关键字,而普通函数中是不可以的。 await关键字有什么特点呢?
-
通常使用await是后面会跟上一个表达式,这个表达式会返回一个Promise;
-
那么await会等到Promise的状态变成fulfilled状态,之后继续执行异步函数
-
如果await后面是一个普通的值,那么会直接返回这个值
-
如果await后面是一个thenable的对象,那么会根据对象的then方法调用来决定后续的值
-
如果await后面的表达式,返回的Promise是reject的状态,那么会将这个reject结果直接作为函数的Promise的 reject值
具体的解释请看下面的代码
async function foo(){
await 表达式(Promise)
}
function requestData(){
return new Promise((resolve,reject) => {
setTimeout(()=>{
resolve(222)
// reject("error message")
},2000)
})
}
async function foo(){
const res = await requestData() //等待这个promise指向结束后返回值
//如果没有结果后面的代码都不会执行
}
function requestData(){
return new Promise((resolve,reject) => {
setTimeout(()=>{
resolve(222)
// reject("error message")
},2000)
})
}
async function foo(){
const res1 = await requestData() //等待这个promise指向结束后返回值
//这里的代码相当于promise中的then
console.log('后面的代码1',res1);
console.log('接着执行');
}
function requestData(){
return new Promise((resolve,reject) => {
setTimeout(()=>{
resolve(222)
// reject("error message")
},2000)
})
}
async function foo(){
const res1 = await requestData() //等待这个promise指向结束后返回值
// 这里后面的多有代码相当于在上面的promise 中then执行
console.log('第一个promise的then执行');
console.log(res1);
const res2 = await requestData()
console.log('第二个promise的then执行');
console.log(res2);
}
await后面跟上普通的值
function requestData(){
return new Promise((resolve,reject) => {
setTimeout(()=>{
resolve(222)
// reject("error message")
},2000)
})
}
//跟上其他的值
async function foo(){
const res1 = await 123 //这里会返回await后面的东西
console.log('res1:',res1); //res1: 123
}
foo()
跟上thenable
async function foo(){
const res1 = await {
then(resolve,reject){
resolve("abc")
}
}
console.log(res1); //abc
}
foo()
跟上promise
async function foo(){
const res1 = await new Promise((resolve) => {
resolve("harry")
})
console.log("res1:",res1); //res1: harry
}
foo()
跟上reject
function requestData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject("error message")
}, 2000)
})
}
//跟上reject值
async function foo() {
const res1 = await requestData()
console.log("res1:", res1);
}
//reject值会当成整个函数的promise
foo().catch(err => {
console.log('err:',err);
})