成都哪里做網(wǎng)站便宜百度的合作網(wǎng)站有哪些
目錄捏
- 前言
- 一、async
- 二、await
- 三、使用方法
- 總結
前言
async / await 是 ES2017(ES8) 提出的基于 Promise 解決異步的最終方案。上一篇文章介紹了 回調地獄 與 Promise(JavaScript),因為 Promise 的編程模型依然充斥著大量的 then 方法,其雖然解決了回調地獄的問題,但是在語義化及代碼可讀性方面依然存在缺陷,這就是 async / await 出現(xiàn)的原因。
一、async
async
(異步):用來聲明一個異步函數(shù);await
(async wait):用來等待異步函數(shù)執(zhí)行- async 是一個加在函數(shù)前的修飾符,被 async 定義的函數(shù)會默認返回一個 Promise 對象 resolve 的值,因此對 async 函數(shù)可以直接使用 then 方法
// 默認返回 Promise 對象成功值async function fun() {console.log('用戶數(shù)據(jù)讀取中~~');return '用戶數(shù)據(jù)讀取成功!!';}fun().then(val => {console.log(val)})
// 根據(jù) Promise 對象決定返回值async function fun() {console.log('用戶數(shù)據(jù)讀取中~~')return new Promise((resolve, reject) => {setTimeout(() => {resolve('用戶數(shù)據(jù)讀取成功!!')}, 3000)})}fun().then(value => {console.log(value)})console.log(1);console.log(2);console.log(3);
二、await
若單有 async,則和 Promise 功能相似,但配合上 await 則效果完全不同
- await 也是一個修飾符,只能放在 async 定義的函數(shù)內
- await 修飾的若是 Promise 對象:可獲取 Promise 中返回的內容( resolve 或 reject 的參數(shù)),并會阻塞該函數(shù)內后面的代碼直到獲取到返回值后語句才會往下執(zhí)行;若不是 Promise 對象:將此非 Promise 的語句當做 await 表達式的結果
// 非 Promise 對象async function fun() {console.log('用戶數(shù)據(jù)讀取中~~');let a = await '用戶數(shù)據(jù)讀取成功!!';console.log(a);}fun()
async function fun() {console.log('用戶數(shù)據(jù)讀取中~~')console.log(1);console.log(2);console.log(3);// Promise 對象let a = await new Promise((resolve, reject) => {setTimeout(() => {resolve('用戶數(shù)據(jù)讀取成功!!')}, 3000)})console.log(a);}fun()
async function fun() {let a = await 768console.log(a)let b = await '用戶數(shù)據(jù)讀取中...'console.log(b)// 注意:此處等待對象為函數(shù),故需通過()調用let c = await function () {return '預計時間:3s'}()console.log(c)let d = await new Promise((resolve, reject) => {setTimeout(function () {resolve('用戶數(shù)據(jù)讀取成功!!')}, 3000)})console.log(d)}fun()
由以上案例可知 await 不僅可以用于等 Promise 對象,還可以等任意表達式,即 await 后面實際是可以接普通函數(shù)調用或者直接量的。不過我們更多的是放一個返回 Promise 對象的表達式,它等待的是 Promise 對象執(zhí)行完畢所返回的結果。
// 非 Promise 對象function notPromise(time) {setTimeout(() => {console.log(time);return 1;}, time)}async function fun() {// 將 notPromise 所執(zhí)行語句當做 await 表達式的結果let a = await notPromise(3000);let b = notPromise(2000);let c = await notPromise(1000);console.log(a);console.log('先執(zhí)行我捏~')}fun();
三、使用方法
// 定義一個異步函數(shù),time秒后才能獲取到值function fun(time) {// Promise 對象return new Promise((resolve, reject) => {setTimeout(() => {resolve('用戶數(shù)據(jù)讀取成功!!')}, time)})}async function test() {console.log(1);console.log(2);console.log(3);// 獲取到 Promise 對象所返回的結果( resolve參數(shù) )let a = await fun(3000);console.log(a)}test()
上一篇文章 回調地獄 與 Promise(JavaScript)中通過 Promise
解決了回調地獄問題,但不斷地調用 then
鏈使代碼看起來十分冗余從而導致可讀性變差,故本文通過 asysc 與 await
來簡化上文代碼。
問題回顧:分別間隔 3s、2s、1s 按順序輸出:
我在定時器1里捏!!
,我在定時器2里捏!!
,我在定時器3里捏!!
await 的優(yōu)勢在于簡化處理 then 鏈,使 異步代碼 的書寫方式更接近于 同步代碼
function promise(value, time) {return new Promise((resolve, reject) => {setTimeout(() => {resolve(value)}, time)})}async function fun() {let a = await promise('我在定時器1里捏!!', 3000)console.log(a);let b = await promise('我在定時器2里捏!!', 2000)console.log(b);let c = await promise('我在定時器3里捏!!', 1000)console.log(c);}fun()
總結
最后我們可以通過三張圖片來直觀對比一下三種寫法:
1.回調地獄
2.Promise
3.async + await
注意
await 必須寫在 async 函數(shù)中, 但 async 函數(shù)中可以沒有 await
在使用 await 的時候我們只是暫停了函數(shù),而非整段代碼
async/await 與 Promise 并不存在誰代替誰的說法,因為 async/await 是寄生于 Promise、Generater 的語法糖。使用 async/await 可以實現(xiàn)用同步代碼的風格來編寫異步代碼,而異步編程的最高境界就是不關心它是否是異步,async/await 很好的解決了這一點。