认识
一、认识
async/await
也是异步编程的一种解决方案,是 Generator
函数的语法糖,同时基于Promise
。async
函数就是将 Generator
函数的星号(*
)替换成async
,将yield
替换成await
,仅此而已。主要的作用是 用同步的方式,执行异步的操作
async
, 在函数前加上 async
关键字,表示该函数内部可能包含异步操作。无论函数内部返回什么,都会被自动包装成一个 Promise
。如果函数返回的是一个值,则返回一个立即 resolve
的 Promise
; 如果返回的是一个 Promise
, 则直接返回该 Promise
。异常处理, 在 async
函数中抛出的异常, 会导致返回的 Promise
被拒绝, 可以通过 .catch()
或 try/catch
捕获错误。
await
, 当执行到 await
表达式时,首先会对其右侧的表达式进行同步求值。如果该表达式返回的是一个非 Promise
值,它会被自动包装为一个立即 resolve
的 Promise
。如果返回的是一个 Promise
,则直接使用该 Promise
。一旦右侧 Promise
状态改变(resolve
或 reject
), await
后面的语句会被放入微任务队列中,等待当前同步任务和其他微任务执行完毕后,再恢复 async
函数的执行。这种机制与调用 .then()
很相似,可以理解为 await
将后续代码隐式地放到了对应 Promise
的 .then()
回调中。
async/await
异常捕获机制: 在 async/await
的模式下, 无论是同步代码中直接抛出的错误, 还是 await
表达式等待的 Promise
被拒绝(即出错), 都会导致整个 async
函数中止执行, 并且这个函数返回的 Promise
会变成 reject
状态, 错误对象会传递给调用者的 .catch()
或通过 try/catch
捕获。
二、语法
function promise1(){
return new Promise((resolve,reject)=>{
});
}
async function async1(){
return 1
}
async function async2(){
try{
const result1 = await promise1();
console.log("result1", result1)
const result2 = await async2();
console.log("result2", result2);
}catch(error){
console.log("error", error);
}
}
三、检测
描述: 如何判断传入的函数是否标记了 async
3.1 Symbol.toStringTag
function isAsyncFunction(func) {
return func[Symbol.toStringTag] === "AsyncFunction";
}
console.log("function >>> ", isAsyncFunction(() => {}));
console.log("async function >>> ", isAsyncFunction(async () => {}));
console.log("function Promise >>> ", isAsyncFunction(() => {return new Promise()}));
3.2 Object.prototype.toString.call
function isAsyncFunction(func) {
return Object.prototype.toString.call(func) === "[object AsyncFunction]";
}
console.log("function >>> ", isAsyncFunction(() => {}));
console.log("async function >>> ", isAsyncFunction(async () => {}));
console.log("function Promise >>> ", isAsyncFunction(() => {return new Promise()}));
四、调用
4.1 函数
4.2 顶层
早期的语法规定是,await
命令只能出现在 async
函数内部,否则都会报错。
五、问题
5.1 async vs generator
-
内置执行器:
Generator
函数的执行必须靠执行器,所以才有了co
模块,而async
函数自带执行器。也就是说,async
函数的执行,与普通函数一模一样,只要一行。 -
更好的语义:
async
和await
,比起星号和yield
,语义更清楚了。async
表示函数里有异步操作,await
表示紧跟在后面的表达式需要等待结果。 -
更广的适用性:
co
模块约定,yield
命令后面只能是Thunk
函数或Promise
对象,而async
函数的await
命令后面,可以是Promise
对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即resolved
的Promise
对象)。 -
返回值是 Promise:
async
函数返回值是Promise
对象,比Generator
函数返回的Iterator
对象方便,可以直接使用then()
方法进行调用