,

为什么 effect 方法前面必须加 *

1. 核心:* 代表 Generator 生成器函数 function* 是 ES6 语法,叫生成器函数,配合…

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 实现同步写法的异步:

  1. yield call(api):暂停执行,等待接口请求完成拿到结果,再往下走;
  2. 可以串行写多个请求,逻辑清晰,不用嵌套回调 /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();
}
  • *async
  • yieldawait

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 });
    }
  }
}

Previous Post

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

About the Author

每个人都有自己得时区,在自己得时区里,一切都是准时的。

BlockSpare — News, Magazine and Blog Addons for (Gutenberg) Block Editor