細(xì)數(shù)promise與async/await的使用及區(qū)別說(shuō)明
簡(jiǎn)單的一張圖可以直觀的表現(xiàn)出 callback、Promise 和 async/await 在使用時(shí)的主要區(qū)別。

一、callback,Promise,async&await三者的區(qū)別?
1.callback 經(jīng)過(guò)深層次的嵌套,會(huì)產(chǎn)生回調(diào)地獄,需手動(dòng)檢查err參數(shù)。
2.promise 通過(guò)鏈?zhǔn)秸{(diào)用,直接在 then 中返回一個(gè) promise 來(lái)進(jìn)行成功之后的回調(diào)函數(shù),用 catch 來(lái)做錯(cuò)誤處理。
3.async/await 則直接將其變成了同步的寫法,既可以用.catch又可以用try-catch捕捉,簡(jiǎn)潔,可讀性強(qiáng),寫法更加優(yōu)雅 。
//try...catch
const fn = () => {
return new Promise((resolve, reject) => {
reject('你錯(cuò)啦~~')
})
}
const asyncFn = async () => {
try {
let result1 = await fn()
} catch (error) {
console.log('try...catch:' + error)
}
}
asyncFn() //try...catch:你錯(cuò)啦~~
//catch
const asyncFn1 = async () => {
const res = await fn().catch(err => console.log('catch:' + err))
}
asyncFn1() //catch:你錯(cuò)啦~~注意: try…catch可以捕獲promise異常嗎?
不能,try…catch 主要用于捕獲異常,這里的異常,是指同步函數(shù)的異常。
二、Promise
1.Promise的特點(diǎn)
1.無(wú)法取消Promise,一旦新建它就會(huì)立即執(zhí)行,無(wú)法中途取消。
2.如果不設(shè)置回調(diào)函數(shù),Promise內(nèi)部拋出的錯(cuò)誤,不會(huì)反應(yīng)到外部。
3.當(dāng)處于pending狀態(tài)時(shí),無(wú)法得知目前進(jìn)展到哪一個(gè)階段(剛剛開始還是即將完成)。
2.Promise的用法
1.Promise的三種狀態(tài)
pending: 進(jìn)行中fulfilled: 成功rejected: 失敗
Promise 構(gòu)造函數(shù)有兩個(gè)參數(shù) resolve和 reject,分別對(duì)應(yīng)成功和失敗后的回調(diào)函數(shù)
2.Promise原型上的方法
then: 成功時(shí)的回調(diào)catch: 失敗時(shí)的回調(diào)finally: 執(zhí)行完畢后無(wú)論其結(jié)果怎樣都做一些處理
3.Promise的靜態(tài)方法
Promise.all()有一個(gè)Promise對(duì)象失敗則全部失敗,輸出第一個(gè)失敗的原因Promise.allSettled()不關(guān)心Promise對(duì)象的成功或者失敗,只關(guān)心結(jié)果Promise.any()返回第一個(gè)成功的Promise對(duì)象Promise.race()返回執(zhí)行最快的那個(gè)Promise對(duì)象,無(wú)論它是成功還是失敗Promise.resolve()返回一個(gè)狀態(tài)為成功的Promise對(duì)象Promise.reject()返回一個(gè)狀態(tài)為失敗的Promise對(duì)象
let p1 = new Promise((resolve, reject) => {
setTimeout(resolve, 400, 'one');
});
let p2 = Promise.reject("two");
let p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, 'three');
});
let p4 = Promise.resolve("four");
let p5 = new Promise((resolve, reject) => {
// reject('reject');
setTimeout(resolve, 500, 'five');
})
Promise.all([p1,p2,p3,p4,p5]).then(values => {
console.log(values,"all");
}).catch((err) => {
console.log(err,"allBad");
})
Promise.allSettled([p1,p2,p3,p4,p5]).then(values => {
console.log(values,"allSettled");
}).catch((err) => {
console.log(err,"allSettledBad");
})
Promise.any([p1,p2,p3,p4,p5]).then(values => {
console.log(values,"any");
}).catch((err) => {
console.log(err,"anyBad");
})
Promise.race([p1,p2,p3,p4,p5]).then(values => {
console.log(values,"race");
}).catch((err) => {
console.log(err,"raceBad");
})3.Promise的運(yùn)用(請(qǐng)結(jié)合js事件循環(huán))
1.紅燈3秒亮一次,綠燈1秒亮一次,黃燈2秒亮一次;如何使用Promise讓三個(gè)燈不斷交替重復(fù)亮燈?
function mylight(value,time){
return new Promise((resolve,reject) => {
setTimeout((params) => {
console.log(value);
resolve()
},time)
})
}
let step =()=>{
Promise.resolve()
.then(() => {
//此處的return是為了執(zhí)行后面的.then
return mylight('red',3000)
})
.then((res) => {
return mylight('green',1000)
})
.then((res) => {
return mylight('yellow',2000)
})
.then(res=>{
// 遞歸執(zhí)行
step()
})
}
step()擴(kuò)展:使用reduce實(shí)現(xiàn)以上代碼?reduce用法
// 用reduce相當(dāng)于往后面疊加.then,跟上面的重復(fù)亮燈代碼一樣
const arr = [
{
color:"red",
time:3000,
},
{
color:'green',
time:1000,
},
{
color:'yellow',
time:2000
}
]
function fn(arr) {
arr.reduce((pre, cur,index) => {
return pre.then(() => {
return new Promise(resolve => {
setTimeout(() => {
resolve(console.log(cur.color))
}, cur.time)
})
})
}, Promise.resolve()).then((params) => {
fn(arr)
})
// 以上代碼簡(jiǎn)寫為:
// arr.reduce((pre, cur) => pre.then(() => new Promise(r => setTimeout(() => r(console.log(cur.color)), cur.time))), Promise.resolve()).then((params) => fn(arr))
}
fn(arr)三、async與await
1.async與await介紹
async await 需成對(duì)出現(xiàn),async await原理是生成器,
async函數(shù)就是將 Generator 函數(shù)的星號(hào)(*)替換成async,將yield替換成await,參照 Generator 封裝的一套異步處理方案,可以理解為 Generator 的語(yǔ)法糖,
而 Generator 又依賴于迭代器Iterator,
而 Iterator 的思想又來(lái)源于單向鏈表。
2.async和await的用法
1 async和await把異步改為同步,得到最新的state的值
使用Promise來(lái)封裝setState(異步編程)
changeCount = (state)=>{
return new Promise((resolve,reject)=>{
setTimeout(()=>{
this.setState(state)
//resolve包裹成功時(shí)的結(jié)果
resolve(this.state.count)
},100)
})
},
pushRouter = async() => {
// await this.setState({
// count:this.state.count+1
// })
const result = await this.changeCount({
count:this.state.count + 1
})
}2 async,await結(jié)合try,catch使用捕獲異常
async componentDidMount() {
const { dispatch } = this.props
try {
const response = await dispatch({
type: "netValueQuery/queryListData",
payload: {}
})
if (response.httpStatus !== 200) {
throw new Error(response.msg);
}
const json = await response.json();
this.setState({ data: json });
} catch (error) {
console.log(error);
}
}3 多個(gè)請(qǐng)求,后面的請(qǐng)求里需使用前面請(qǐng)求里返回的值
getSign(result){
return this.$post(`/share/saveRecord`)
},
getTask() {
const actid = this.$route.query.id;
return this.$get(`/lottery/powerTask/${actid}`);
},
async getReady(){
const task = await this.getTask()
this.result = task.data.find(item => item.name.includes("分享"))
const str = await this.getSign(this.result)
},以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于對(duì)TypeScript泛型參數(shù)的默認(rèn)值理解
泛型可以理解為寬泛的類型,通常用于類和函數(shù),下面這篇文章主要給大家介紹了關(guān)于對(duì)TypeScript泛型參數(shù)默認(rèn)值的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
微信小程序?qū)崿F(xiàn)基于三元運(yùn)算驗(yàn)證手機(jī)號(hào)/姓名功能示例
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)基于三元運(yùn)算驗(yàn)證手機(jī)號(hào)/姓名功能,涉及三元運(yùn)算符的判定及字符串正則驗(yàn)證相關(guān)操作技巧,需要的朋友可以參考下2019-01-01
WordPress 單頁(yè)面上一頁(yè)下一頁(yè)的實(shí)現(xiàn)方法【附代碼】
下面小編就為大家?guī)?lái)一篇WordPress 單頁(yè)面上一頁(yè)下一頁(yè)的實(shí)現(xiàn)方法【附代碼】。小編覺得非常不錯(cuò)。給大家分享一下。希望能給大家一個(gè)參考。2016-03-03
javascript元素動(dòng)態(tài)創(chuàng)建實(shí)現(xiàn)方法
這篇文章主要介紹了javascript元素動(dòng)態(tài)創(chuàng)建實(shí)現(xiàn)方法,涉及javascript操作元素的相關(guān)技巧,需要的朋友可以參考下2015-05-05
js 判斷一組日期是否是連續(xù)的簡(jiǎn)單實(shí)例
下面小編就為大家?guī)?lái)一篇js 判斷一組日期是否是連續(xù)的簡(jiǎn)單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-07-07
php+js實(shí)現(xiàn)倒計(jì)時(shí)功能
由PHP傳入JS處理的時(shí)間戳我說(shuō)怎么老是對(duì)不上號(hào)呢,原來(lái)JS時(shí)間戳為13位,包含3位毫秒的,而PHP只有10位不包含毫秒的。恩,基礎(chǔ)還是要補(bǔ)補(bǔ)的2014-06-06
基于js?+?html2canvas實(shí)現(xiàn)網(wǎng)頁(yè)放大鏡功能
最近接到任務(wù),需實(shí)現(xiàn)【網(wǎng)頁(yè)】放大鏡的效果,百度搜索?【js?放大鏡】關(guān)鍵字,千篇一律的都是一些仿淘寶/京東等電商網(wǎng)站中查看規(guī)格大圖的效果實(shí)現(xiàn),根本無(wú)法滿足我的需求,于是自己花了點(diǎn)時(shí)間調(diào)研實(shí)現(xiàn),在這里分享給大家,感興趣的朋友可以參考下2023-12-12

