在平时开发中,虽然咱们都会尽量的去避免接口串行调用,可是在某种特定场景下没法避免要这样作。下面将介绍一些常见的方法以及存在的问题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 ''; }`