async与await的关系
async
实际上是一个Promise
,return
的值以Promise
的resolve
状态返回
const a = async () => {
return "Hello, async!"; // 可以看成resolve("Hello, async!")
}
console.log(a() instanceof Promise); // true
如果async
内部没有return
返回,则默认返回undefined
因为async
是一个Promise
,所以可以用await
来获取Prmose
的返回值
const a = async () => {
return "Hello, async!";
}
const b = async () => {
let c = await a();
console.log(c); // Hello, async!
}
b()
await
只能再async
内部使用,所以async-await
是一个语法糖,async
可以没有await
,但await
不能没有async
由于async
是Promise
,所以上面例子中,b
函数也是一个Promise
const a = async () => {
return "Hello, async!";
}
const b = async () => {
const c = await a();
console.log(c); // Hello, async!
}
console.log(b() instanceof Promise)
关于执行顺序
const a = async () => {
console.log("同步代码-2")
return "promise返回"
}
const b = async () => {
console.log("同步代码-1")
a().then(item => console.log(item));
console.log("同步代码-3")
}
b()
async
虽然是一个Prmoise
,但它是按照同步方式执行的,它返回的值是一个Promise
的reject
(微任务),所以在上述代码中,async
的返回值是一个异步,会最后执行。
const a = async () => {
console.log("同步代码-2")
return "promise返回"
}
const b = async () => {
console.log("同步代码-1")
let item = await a()
console.log(item)
console.log("同步代码-3")
}
b()
想要让async
的返回值同步执行,可以在内部使用await
,使其变为同步执行,当await
执行后,后续的代码才会执行。(如果await
的函数内部还有定时等异步任务,那么那么还会再细分,定时器是一个异步宏任务,肯定排在同步、微任务之后,这里就考验对事件循环的掌握程度)
如果你定义了async
,如果不用async
函数的返回值,那么在调用async
函数时,可以不用在前面添加await
,一位内async
本身就是一个立即执行函数。
虽然使用 async 关键字定义的函数可以包含异步操作,但是 async 函数本身在执行时是按照同步的方式进行的。这意味着,当调用一个包含 async 关键字定义的函数时,它会立即返回一个 Promise 对象,并且函数体内的代码会按照同步的方式执行,但其中的异步操作会被放入微任务队列中等待执行。
因此,从调用 async 函数的角度来看,它的执行似乎是同步的,因为它会立即返回一个 Promise 对象,而不会等待异步操作的完成。但实际上,异步操作会在当前同步任务执行完毕后,根据事件循环的机制被执行,这就是为什么我们可以在 async 函数内部使用 await 关键字来等待异步操作完成。
综上所述,虽然 async 函数的执行表现为同步,但它实际上还是异步执行的,因为它可以包含异步操作,并且会返回一个 Promise 对象来表示异步操作的最终结果。
async-await的错误捕获
async-await
的错误捕获,由于await
或阻塞任务,一单报错不捕获错误会引起进程阻塞,需要catch
,通常会用try\catch
async function getPromise(){
try {
let data = await promise();
console.log('async',data);
} catch(err) {
console.log('await报错',err);
}
}
async-await
是一个promise
,所以可以直接捕获错误,你也可以这样简写
async function getPromise2() {
let data = await primise().catch(err=>console.log(err))
if(!data) return // 返回为空则证明是错误返回,中断
console.log('后续逻辑',data)
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。