1. 核心:* 代表 Generator 生成器函数
function* 是 ES6 语法,叫生成器函数,配合 yield 关键字使用;
Dva 的 effects 全部要求写成生成器函数,不加 * 直接报错、yield 无法生效。
2. yield 只能在带 * 的函数内使用
代码里有 yield call(xxx)、yield put():
yield是暂停、等待异步执行完成的关键字;- 普通函数
login(){}里不允许写 yield,浏览器直接报语法错误; - 只有
*login(){}生成器函数,才能识别yield。
3. Dva 为什么 effect 强制用 Generator?
effect 专门处理异步逻辑(接口请求、延时、多个串行接口),靠 yield 实现同步写法的异步:
yield call(api):暂停执行,等待接口请求完成拿到结果,再往下走;- 可以串行写多个请求,逻辑清晰,不用嵌套回调 /async await;
*login({payload}, {call, put}) {
// 先等登录接口完成
const res = yield call($http.userLogin, payload);
// 拿到结果后,再更新state
yield put({ type: 'saveUserInfo', payload: res.data });
}
和 async/await 简单类比
// Generator 写法(Dva effect 固定格式)
*login(_, {call}) {
const res = yield call(api());
}
// 等价普通异步写法
async login() {
const res = await api();
}
*≈asyncyield≈await
4. 补充区分 reducer /effect
reducers:纯同步函数,不用加*、不能用 yield,只修改 state;effects:异步逻辑专用,必须加*、依靠 yield 处理异步。
示例完整区分:
export default {
namespace: 'user',
state: { userInfo: null },
// reducer:同步,无*
reducers: {
saveInfo(state, { payload }) {
state.userInfo = payload;
}
},
// effect:异步,必须带*
effects: {
*login({ payload }, { call, put }) {
const data = yield call($http.userLogin, payload);
yield put({ type: 'saveInfo', payload: data });
}
}
}




