ES7之Async/await的使用詳解
在 js 異步請(qǐng)求數(shù)據(jù)時(shí),通常,我們多采用回調(diào)函數(shù)的方式解決,但是,如果有多個(gè)回調(diào)函數(shù)嵌套時(shí),代碼顯得很不優(yōu)雅,維護(hù)成本也相應(yīng)較高。 ES6 提供的 Promise 方法和 ES7 提供的 Async/Await 語(yǔ)法糖可以更好解決多層回調(diào)問(wèn)題。
Promise 對(duì)象用于表示一個(gè)異步操作的最終狀態(tài)(完成或失?。?,以及其返回的值。
await 操作符用于等待一個(gè)Promise 對(duì)象。它只能在異步函數(shù) async function 中使用。
await 表達(dá)式會(huì)暫停當(dāng)前 async function 的執(zhí)行,等待 Promise 處理完成。若 Promise 正常處理(fulfilled),其回調(diào)的resolve函數(shù)參數(shù)作為 await 表達(dá)式的值,繼續(xù)執(zhí)行 async function。
一個(gè)ajax請(qǐng)求時(shí)
通常 使用 ajax 請(qǐng)求數(shù)據(jù)時(shí),會(huì)
$.ajax({
url: 'data1.json',
type: 'GET',
success: function (res) {
console.log(res) // 請(qǐng)求成功,則得到結(jié)果res
},
error: function(err) {
console.log(err)
}
})
上面可以得到我們想要的結(jié)果 res ---> { "url": "data2.json" }
多個(gè)ajax請(qǐng)求時(shí)
但是 當(dāng)?shù)玫降臄?shù)據(jù) res 需要用于另一個(gè) ajax 請(qǐng)求時(shí),則需要如下寫(xiě)法:
$.ajax({
url: 'data1.json',
type: 'GET',
success: function (res) {
$.ajax({
url: res.url, // 將 第一個(gè)ajax請(qǐng)求成功得到的res 用于第二個(gè)ajax請(qǐng)求
type: 'GET',
success: function (res) {
$.ajax({
url: res.url, // 將第二個(gè)ajax請(qǐng)求成功得到的res 用于第三個(gè)ajax請(qǐng)求
type: 'GET',
success: function (res) {
console.log(res) // {url: "this is data3.json"}
},
error: function(err) {
console.log(err)
}
})
},
error: function(err) {
console.log(err)
}
})
},
error: function(err) {
console.log(err)
}
})
上面出現(xiàn)多個(gè)回調(diào)函數(shù)的嵌套,可讀性較差(雖然這種嵌套在平常的開(kāi)發(fā)中少見(jiàn),但是在node服務(wù)端開(kāi)發(fā)時(shí),還是很常見(jiàn)的)
優(yōu)化方法
使用 promise 鏈?zhǔn)讲僮?/strong>
如下,使用 Promise,進(jìn)行鏈?zhǔn)讲僮鳎梢允股厦娴漠惒酱a看起來(lái)如同步般易讀,從回調(diào)地獄中解脫出來(lái)。。
function ajaxGet (url) {
return new Promise(function (resolve, reject) {
$.ajax({
url: url,
type: 'GET',
success: function (res) {
resolve(res);
},
error: function(err) {
reject('請(qǐng)求失敗');
}
})
})
};
ajaxGet('data1.json').then((d) => {
console.log(d); // {url: "data2.json"}
return ajaxGet(d.url);
}).then((d) => {
console.log(d); // {url: "data3.json"}
return ajaxGet(d.url);
}).then((d) => {
console.log(d); // {url: "this is data3.json"}
})
Async/await 方法
- async 表示這是一個(gè)async函數(shù),即異步函數(shù),await只能用在這個(gè)函數(shù)里面。
- await 表示在這里等待promise返回結(jié)果了,再繼續(xù)執(zhí)行。
- await 后面跟著的應(yīng)該是一個(gè)promise對(duì)象(當(dāng)然,其他返回值也沒(méi)關(guān)系,只是會(huì)立即執(zhí)行,不過(guò)那樣就沒(méi)有意義了…)
- await 操作符用于等待一個(gè)Promise 對(duì)象。它只能在異步函數(shù) async function 中使用。
- await 等待的雖然是promise對(duì)象,但不必寫(xiě).then(..),直接可以得到返回值。
執(zhí)行一個(gè)ajax請(qǐng)求,可以通過(guò)如下方法:
function ajaxGet (url) {
return new Promise(function (resolve, reject) {
$.ajax({
url: url,
type: 'GET',
success: function (res) {
resolve(res)
},
error: function(err) {
reject('請(qǐng)求失敗')
}
})
})
};
async function getDate() {
console.log('開(kāi)始')
let result1 = await ajaxGet('data1.json');
console.log('result1 ---> ', result1); // result1 ---> {url: "data2.json"}
};
getDate(); // 需要執(zhí)行異步函數(shù)
執(zhí)行多個(gè)ajax請(qǐng)求時(shí):
function ajaxGet (url) {
return new Promise(function (resolve, reject) {
$.ajax({
url: url,
type: 'GET',
success: function (res) {
resolve(res)
},
error: function(err) {
reject('請(qǐng)求失敗')
}
})
})
};
async function getDate() {
console.log('開(kāi)始')
let result1 = await ajaxGet('data1.json');
let result2 = await ajaxGet(result1.url);
let result3 = await ajaxGet(result2.url);
console.log('result1 ---> ', result1); // result1 ---> {url: "data2.json"}
console.log('result2 ---> ', result2); // result2 ---> {url: "data3.json"}
console.log('result3 ---> ', result3); // result3 ---> {url: "this is data3.json"}
};
getDate(); // 需要執(zhí)行異步函數(shù)
async await捕捉錯(cuò)誤:
async await中.then(..)不用寫(xiě)了,那么.catch(..)也不用寫(xiě),可以直接用標(biāo)準(zhǔn)的try catch語(yǔ)法捕捉錯(cuò)誤。
例如,如果下面的 url 寫(xiě)錯(cuò)了
function ajaxGet (url) {
return new Promise(function (resolve, reject) {
$.ajax({
url: url111, // 此處為錯(cuò)誤的 url
type: 'GET',
success: function (res) {
resolve(res)
},
error: function(err) {
reject('請(qǐng)求失敗')
}
})
})
};
async function getDate() {
console.log('開(kāi)始')
try {
let result1 = await ajaxGet('data1.json'); // 執(zhí)行到這里報(bào)錯(cuò),直接跳至下面 catch() 語(yǔ)句
let result2 = await ajaxGet(result1.url);
let result3 = await ajaxGet(result2.url);
console.log('result1 ---> ', result1);
console.log('result2 ---> ', result2);
console.log('result3 ---> ', result3);
} catch(err) {
console.log(err) // ReferenceError: url111 is not defined
}
};
getDate(); // 需要執(zhí)行異步函數(shù)
源碼
源碼查看
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Javascript BOM學(xué)習(xí)小結(jié)(六)
BOM:BrowserObjectModel,瀏覽器對(duì)象模型,提供JS中對(duì)瀏覽器的各種操作的對(duì)象,是JS應(yīng)用中唯一沒(méi)有相關(guān)標(biāo)準(zhǔn)的部分,這事BOM經(jīng)常出現(xiàn)問(wèn)題的所在,主要用于處理瀏覽器窗口與框架,瀏覽器特有的JS擴(kuò)展也被默認(rèn)為BOM的一部分,而各瀏覽器之間的公有對(duì)象就成了默認(rèn)的標(biāo)準(zhǔn)2015-11-11
2007/12/23更新創(chuàng)意無(wú)限,簡(jiǎn)單實(shí)用(javascript log)
在javascript開(kāi)發(fā)過(guò)程中,如果總是使用alert的方式調(diào)試程序,在某些簡(jiǎn)單的程序中是可行的. 但是在通常的項(xiàng)目很復(fù)雜,這種方式已經(jīng)很難滿足,企業(yè)級(jí)開(kāi)發(fā)的需要。2007-12-12
在JS中最??吹角凶钊菀酌曰蟮恼Z(yǔ)法(轉(zhuǎn))
發(fā)現(xiàn)一篇JS中比較容易迷惑的語(yǔ)法的解釋,挺有用的,轉(zhuǎn)載下,與大家分享2010-10-10
原生JavaScript實(shí)現(xiàn)刮刮樂(lè)
這篇文章主要為大家詳細(xì)介紹了原生JavaScript實(shí)現(xiàn)刮刮樂(lè),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-09-09
javascript獲取URL參數(shù)與參數(shù)值的示例代碼
本篇文章主要是對(duì)javascript獲取URL參數(shù)與參數(shù)值的示例代碼進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-12-12
Nuxt3?布局layouts和NuxtLayout的使用詳解
layouts是Nuxt3提供的一種方便開(kāi)發(fā)者快速實(shí)現(xiàn)自定義布局的約定,是基于Vue3的一個(gè)開(kāi)發(fā)框架,基于服務(wù)器端渲染SSR,可以更加方便的用于Vue的SEO優(yōu)化,這篇文章主要介紹了Nuxt3?布局layouts和NuxtLayout的使用,需要的朋友可以參考下2023-04-04
JS實(shí)現(xiàn)的驗(yàn)證身份證及獲取地區(qū)功能示例
這篇文章主要介紹了JS實(shí)現(xiàn)的驗(yàn)證身份證及獲取地區(qū)功能,結(jié)合實(shí)例形式分析了JS字符串、數(shù)組及正則操作相關(guān)技巧,需要的朋友可以參考下2017-01-01

