細數(shù)promise與async/await的使用及區(qū)別說明
簡單的一張圖可以直觀的表現(xiàn)出 callback、Promise 和 async/await 在使用時的主要區(qū)別。
一、callback,Promise,async&await三者的區(qū)別?
1.callback 經(jīng)過深層次的嵌套,會產(chǎn)生回調(diào)地獄,需手動檢查err參數(shù)。
2.promise 通過鏈式調(diào)用,直接在 then 中返回一個 promise 來進行成功之后的回調(diào)函數(shù),用 catch 來做錯誤處理。
3.async/await 則直接將其變成了同步的寫法,既可以用.catch又可以用try-catch捕捉,簡潔,可讀性強,寫法更加優(yōu)雅 。
//try...catch const fn = () => { return new Promise((resolve, reject) => { reject('你錯啦~~') }) } const asyncFn = async () => { try { let result1 = await fn() } catch (error) { console.log('try...catch:' + error) } } asyncFn() //try...catch:你錯啦~~ //catch const asyncFn1 = async () => { const res = await fn().catch(err => console.log('catch:' + err)) } asyncFn1() //catch:你錯啦~~
注意: try…catch可以捕獲promise異常嗎?
不能,try…catch 主要用于捕獲異常,這里的異常,是指同步函數(shù)的異常。
二、Promise
1.Promise的特點
1.無法取消Promise,一旦新建它就會立即執(zhí)行,無法中途取消。
2.如果不設置回調(diào)函數(shù),Promise內(nèi)部拋出的錯誤,不會反應到外部。
3.當處于pending狀態(tài)時,無法得知目前進展到哪一個階段(剛剛開始還是即將完成)。
2.Promise的用法
1.Promise的三種狀態(tài)
pending
: 進行中fulfilled
: 成功rejected
: 失敗
Promise 構造函數(shù)有兩個參數(shù) resolve和 reject,分別對應成功和失敗后的回調(diào)函數(shù)
2.Promise原型上的方法
then
: 成功時的回調(diào)catch
: 失敗時的回調(diào)finally
: 執(zhí)行完畢后無論其結果怎樣都做一些處理
3.Promise的靜態(tài)方法
Promise.all()
有一個Promise對象失敗則全部失敗,輸出第一個失敗的原因Promise.allSettled()
不關心Promise對象的成功或者失敗,只關心結果Promise.any()
返回第一個成功的Promise對象Promise.race()
返回執(zhí)行最快的那個Promise對象,無論它是成功還是失敗Promise.resolve()
返回一個狀態(tài)為成功的Promise對象Promise.reject()
返回一個狀態(tài)為失敗的Promise對象
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的運用(請結合js事件循環(huán))
1.紅燈3秒亮一次,綠燈1秒亮一次,黃燈2秒亮一次;如何使用Promise讓三個燈不斷交替重復亮燈?
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()
擴展:使用reduce實現(xiàn)以上代碼?reduce用法
// 用reduce相當于往后面疊加.then,跟上面的重復亮燈代碼一樣 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) }) // 以上代碼簡寫為: // 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 需成對出現(xiàn),async await原理是生成器,
async函數(shù)就是將 Generator 函數(shù)的星號(*)替換成async,將yield替換成await,參照 Generator 封裝的一套異步處理方案,可以理解為 Generator 的語法糖,
而 Generator 又依賴于迭代器Iterator,
而 Iterator 的思想又來源于單向鏈表。
2.async和await的用法
1 async和await把異步改為同步,得到最新的state的值
使用Promise來封裝setState(異步編程)
changeCount = (state)=>{ return new Promise((resolve,reject)=>{ setTimeout(()=>{ this.setState(state) //resolve包裹成功時的結果 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結合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 多個請求,后面的請求里需使用前面請求里返回的值
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) },
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
微信小程序實現(xiàn)基于三元運算驗證手機號/姓名功能示例
這篇文章主要介紹了微信小程序實現(xiàn)基于三元運算驗證手機號/姓名功能,涉及三元運算符的判定及字符串正則驗證相關操作技巧,需要的朋友可以參考下2019-01-01WordPress 單頁面上一頁下一頁的實現(xiàn)方法【附代碼】
下面小編就為大家?guī)硪黄猈ordPress 單頁面上一頁下一頁的實現(xiàn)方法【附代碼】。小編覺得非常不錯。給大家分享一下。希望能給大家一個參考。2016-03-03javascript元素動態(tài)創(chuàng)建實現(xiàn)方法
這篇文章主要介紹了javascript元素動態(tài)創(chuàng)建實現(xiàn)方法,涉及javascript操作元素的相關技巧,需要的朋友可以參考下2015-05-05基于js?+?html2canvas實現(xiàn)網(wǎng)頁放大鏡功能
最近接到任務,需實現(xiàn)【網(wǎng)頁】放大鏡的效果,百度搜索?【js?放大鏡】關鍵字,千篇一律的都是一些仿淘寶/京東等電商網(wǎng)站中查看規(guī)格大圖的效果實現(xiàn),根本無法滿足我的需求,于是自己花了點時間調(diào)研實現(xiàn),在這里分享給大家,感興趣的朋友可以參考下2023-12-12