实现一个小小的需求
- 弹窗在打开的时候请求图书信息
- 把接口返回的图书信息填充到表单
代码实现
async function formOnMount() {
const bookInfo = await getCurrentBookInfo();
form.setValues(bookInfo);
}
function getCurrentBookInfo(): Promise<Record<string, string>> {
return dispatch<BookManagerModel, Promise<Record<string, string>>>({
type: 'bookManagerModel/getCurrentBookInfo'
});
}
* getCurrentBookInfo(_, {call, select}) {
const id = yield select((state: AllModels) => state.bookManagerModel.currentBookId);
const temp = yield call(apis.getCurrentBookInfo, id);
if (temp.code === '200') {
return temp.data;
}
return ({});
}
我们试着来把 formOnMount
方法改成函数式的
function formOnMount() {
composeAsync<void, void>(getCurrentBookInfo, form.setValues)();
}
换个取巧的方法实现await
关键字
function formOnMount() {
const action = composeAsync<void, void>(
async () => await getCurrentBookInfo(),
form.setValues
);
action()
}
我们找找无法实现await
关键字的原因
export const compose = <T, K>(...funcList: Function[]) => {
if (funcList.length === 0) {
return (arg: T) => arg as unknown as K
}
if (funcList.length === 1) {
return funcList[0] as (arg: T) => K
}
const func = funcList.reduce((a, b) => (...args: Function[]) => b(a(...args)))
return func as unknown as (arg: T) => K;
}
export const pipe = compose;
- 问题就出在
func
上,func
是通过funcList
的reduce
方法生成的,可以看到生成的是一个普通的函数,并不支持await
关键字
我们来改造一下compose
方法,新写一个composeAsync
export const composeAsync = <T, K>(...funcList: Function[]) => {
if (funcList.length === 0) {
return async (arg: T) => await arg as unknown as K
}
if (funcList.length === 1) {
return async (arg: T) => await funcList[0](arg) as (arg: T) => K
}
const func = funcList.reduce((a, b) => async (...args: Function[]) => await b(await a(...args)));
return func as unknown as (arg: T) => K;
}
export const pipeAsync = composeAsync;
使用composeAsync
来实现需求
function formOnMount() {
composeAsync<void, void>(getCurrentBookInfo, form.setValues)();
}
总结
- 你可能没意识到你实现了了一个怎样强大的基础功能性方法
compose
把一个个函数像管子一样拼接起来,数据在管子中流动的时候可以很自然的从开头流到结尾
- 但是
composeAsync
在把函数像管子一样拼接起来时,在连接处加了一个开关,如果数据在上个管道中没处理完,是不会流入到下一段管道中的
- 这个开关就是
await
关键字
async
await
语法在错误捕获的时候是个短板,同样的,错误捕获在函数式编程里也不好搞
- 写的时候注意一下,记得在数据处理失败时
return
一个默认值