Redux saga多个api调用

时间:2017-03-01 03:39:28

标签: reactjs redux redux-saga

我有一堆使用redux-saga的api调用的动作观察者。问题是我想制作 ONE 动作监视器,它会激活所有这些动作观察者以获取所有api,而不必重复我已有的代码。如果其中一个观察者返回被拒绝的Promise,它应该取消所有其他观察者。这样做的最佳方式是什么?

function* watchFetchUsers() {
    while(true) {
        yield take([FETCH_USERS]);
        try {
            const users = yield call(api.fetchUserData);
            yield put({ type:FETCH_USERS, payload: users });    
        } catch (err) {
            yield put({ type:SIGNOUT, status: err });
            return err;
        }
    }
}

function* watchFetchDepartments() {
    while(true) {
        yield take([FETCH_DEPARTMENTS]);
        try {
            const departments = yield call(api.fetchDepartmentData);
            yield put({ type:FETCH_DEPARTMENTS, payload: departments });    
        } catch (err) {
            yield put({ type:SIGNOUT, status: err });
            return err;
        }
    }
}

function* watchFetchPositions() {
    while(true) {
        yield take([FETCH_POSITIONS]);
        try {
            const positions = yield call(api.fetchPositionData);
            yield put({ type:FETCH_POSITIONS, payload: positions });    
        } catch (err) {
            yield put({ type:SIGNOUT, status: err });
            return err;
        }
    }
}

function* watchFetchBanks() {
    while(true) {
        yield take([FETCH_BANKS]);
        try {
            const banks = yield call(api.fetchBankData);
            yield put({ type:FETCH_BANKS, payload: banks });    
        } catch (err) {
            yield put({ type:SIGNOUT, status: err });
            return err;
        }
    }
}

function* watchFetchAuthenticatedUser() {
    while(true) {
        yield take([FETCH_AUTHENTICATED_USER]);
        try {
            const user = yield call(api.fetchAuthenticatedUser);
            yield put({ type:FETCH_AUTHENTICATED_USER, payload: user });    
        } catch (err) {
            yield put({ type:SIGNOUT, status: err });
            return err;
        }
    }
}

export default function* fetchData() {
    yield [
        fork(watchFetchUsers),
        fork(watchFetchDepartments),
        fork(watchFetchPositions),
        fork(watchFetchBanks),
        fork(watchFetchAuthenticatedUser)
    ];
}

2 个答案:

答案 0 :(得分:1)

这个怎么样

export function* watchFetchAll() {
  while(true) {
    // const {type} = yield take(['FETCH_A', 'FETCH_B', ...]);
    const {type} = yield take(action => /^FETCH_/.test(action.type));
    console.log('type %s', type);
    try {
      const data = yield call(api.fetch, type);
      console.log('data', data);
      yield put({type, payload: data})
    }
    catch (error) {
      console.log('error', error);
      yield put({ type: 'SIGNOUT', status: error })
    }
  }
}

export default function* fetchData() {
    yield *watchFetchAll();
}

简单的api实现:

const api = {
  fetch(type) {
    switch (type) {
      case 'FETCH_A': return Promise.resolve({result: 'Fetched A type'});
      case 'FETCH_B': return Promise.resolve({result: 'Fetched B type'});
      // other cases
      default: console.log(`Unknown type ${type}`);
    }
  }
};

答案 1 :(得分:0)

分叉任务的错误会传播到父任务。 我不确定下面是否是你想要的。但也许它会起作用。

function* watchFetchUsers() {
    while(true) {
        yield take([FETCH_USERS]);
        const users = yield call(api.fetchUserData);
        yield put({ type:FETCH_USERS, payload: users });    
    }
}

function* watchFetchDepartments() {
    while(true) {
        yield take([FETCH_DEPARTMENTS]);
        const departments = yield call(api.fetchDepartmentData);
        yield put({ type:FETCH_DEPARTMENTS, payload: departments });    
    }
}

function* watchFetchPositions() {
    while(true) {
        yield take([FETCH_POSITIONS]);
        const positions = yield call(api.fetchPositionData);
        yield put({ type:FETCH_POSITIONS, payload: positions });    
    }
}

function* watchFetchBanks() {
    while(true) {
        yield take([FETCH_BANKS]);
        const banks = yield call(api.fetchBankData);
        yield put({ type:FETCH_BANKS, payload: banks });    
    }
}

function* watchFetchAuthenticatedUser() {
    while(true) {
        yield take([FETCH_AUTHENTICATED_USER]);
        const user = yield call(api.fetchAuthenticatedUser);
        yield put({ type:FETCH_AUTHENTICATED_USER, payload: user });   
    }
}

export default function* fetchData() {
    while (true) {
        let tasks;
        try {
           tasks = yield [
                fork(watchFetchUsers),
                fork(watchFetchDepartments),
                fork(watchFetchPositions),
                fork(watchFetchBanks),
                fork(watchFetchAuthenticatedUser)
            ];
            yield join(...tasks)
        } catch (e) {
           yield cancel(...tasks);
           yield put({ type:SIGNOUT, status: err });
        }
    }
}

或者,如果您不想恢复任务,

//....
export default function* fetchData() {
    try {
        yield [
            fork(watchFetchUsers),
            fork(watchFetchDepartments),
            fork(watchFetchPositions),
            fork(watchFetchBanks),
            fork(watchFetchAuthenticatedUser)
        ];
    } catch (e) {
        yield put({ type:SIGNOUT, status: err });
    }
}