在平時開發中,雖然咱們都會盡量的去避免接口串行調用,可是在某種特定場景下沒法避免要這樣作。下面將介紹一些常見的方法以及存在的問題segmentfault
在promise
還未出世以前,回調是最多見的串行方案,可是若是回調嵌套過多會致使代碼的可讀性很是差,不便於維護。promise
假設如今存在一種場景,須要渲染一個表格,可是表格數據接口(/tableList
)須要一個userId
做爲入參,userId
只能經過用戶數據接口(/user
)獲取異步
const Main = (props: IProps) => { const { mainStore } = props; const { fecthUserInfo, fetchTableList } = mainStore as MainStore; useEffect(() => { // 將獲取表格數據的方法做爲回調 fecthUserInfo(fetchTableList) }) return ( <div> <TableList></TableList> </div> ) }
請求回調async
fecthUserInfo = async (cb: (userId: string) => void) => { try { const { code, data } = await fecthUserInfo(); if (code === 200 && !!data) { cb(data.userId) } } catch (error) { console.log(error); } }
promise
的出現就是爲了解決上面嵌套回調,採用更加優雅的方式(鏈式調用)書寫回調函數
使用promise
實現上面回調fetch
const Main = (props: IProps) => { const { mainStore } = props; const { fecthUserInfo, fetchTableList } = mainStore as MainStore; useEffect(() => { fecthUserInfo().then((userId) => { if (userId) { fetchTableList(userId) } }) }) return ( <div> <TableList></TableList> </div> ) }
由於async
函數返回的是一個promise
對象,所以能夠將獲取到的userId
直接返回獲得一個含有userId
的promise
對象this
fecthUserInfo = async () => { try { const { code, data } = await fecthUserInfo(); if (code === 200 && !!data) { return data.userId; } } catch (error) { console.log(error); } return ''; }
對於promise不熟悉的同窗能夠參考通俗淺顯的理解Promise中的thenspa
promise
鏈式回調的方式也會出現很長的狀況,其實對於開發人員最直觀的方法就是執行完一個再執行下一個的這種同步式寫法。而async/await
就是在這種設想下出現的。code
const Main = (props: IProps) => { const { mainStore } = props; const { fecthUserInfo, fetchTableList } = mainStore as MainStore; const init = async () => { const userId = await fecthUserInfo(); if (userId) { fetchTableList(userId); } } useEffect(() => { init(); }) return ( <div> <TableList></TableList> </div> ) }
fecthUserInfo = async () => { try { const { code, data } = await fecthUserInfo(); if (code === 200 && !!data) { return data.userId; } } catch (error) { console.log(error); } return ''; }
假設表格接口須要單號id來獲取,id又須要獲取單號接口根據userId來獲取,而userId是經過用戶接口獲取的。先看一種錯誤的寫法:對象
const Main = (props: IProps) => { const { mainStore } = props; const { fecthUserInfo, fetchTableList } = mainStore as MainStore; const init = async () => { const id = await fecthUserInfo(); if (id) { fetchTableList(id); } } useEffect(() => { init(); }) return ( <div> <TableList></TableList> </div> ) }
@action fetchTableList = async (userId: string) => { try { const { code, data } = await fetchTableData(userId); if (code === 200 && !!data) { runInAction(() => { this.list = data; }) } } catch (error) { console.log(error); } } @action fetchOrder = async (userId: string) => { try { const { code, data } = await fetchOrder(userId); console.log(11111111) if (code === 200 && !!data) { return data.id; } } catch (error) { console.log(error); } return ''; } @action fecthUserInfo = async () => { try { const { code, data } = await fecthUserInfo(); if (code === 200 && !!data) { this.fetchOrder(data.userId) } } catch (error) { console.log(error); } return ''; }
上面會在將不能獲取到id
,fecthUserInfo
方法中不會等到this.fetchOrder(data.userId)
請求完在返回,由於this.fetchOrder
是一個異步函數,會先執行後面的return ''
,所以獲得的id
是空的。
只須要將fecthUserInfo
稍做修改就可正確獲取
@action fecthUserInfo = async () => { try { const { code, data } = await fecthUserInfo(); if (code === 200 && !!data) { return await this.fetchOrder(data.userId) } } catch (error) { console.log(error); } return ''; }`