Redux 是一个流行的 JavaScript 应用程序状态管理库。 它可以使您的应用程序更具可预测性,可维护性和可测试性。 Redux-Saga 是 Redux 的中间件之一,可以帮助您编写更好的异步代码。 本文将为您介绍 Redux-Saga 的使用方法,并提供详细的示例代码。
Redux-Saga 概述
Redux-Saga 是 Redux 的中间件之一。 它使用 ES6 的生成器功能和 JS 协定,以声明性的方式编写异步代码。 这种方法可以使应用程序逻辑更加清晰和可读。
使用 Redux-Saga,您可以轻松地处理各种异步条件,例如 AJAX 调用,WebSockets 或定时器。 此外,它还使得在 Redux 中存储和管理副作用(例如 API 调用或路由导航等操作)更加容易。
安装
使用 Redux-Saga 前,需要先安装它。 这可以通过 npm 来完成。
npm install redux-saga
学习 Redux-Saga
为了学习 Redux-Saga,我们将以一个简单的示例开始,然后逐步扩展该示例以显示各种使用场景。
示例 1:Hello Saga
我们将首先编写下面的代码:
// www.javascriptcn.com code example
import { put, takeEvery } from 'redux-saga/effects';
function* helloSaga() {
console.log('Hello Saga!');
}
function* watchHelloSaga() {
yield takeEvery('HELLO', helloSaga);
}
export default watchHelloSaga;此代码输出 "Hello Saga!"。 然后,我们使用 takeEvery 功能将 helloSaga 绑定到项目中的 "HELLO" 操作。 这意味着每次 "HELLO" 操作被调用时,都会使用 helloSaga 执行。
示例 2:异步调用
在这个示例中,我们将学习如何使用异步函数编写将向 API 发出请求的应用程序。
// www.javascriptcn.com code example
import { takeLatest, call, put } from 'redux-saga/effects';
import Api from '...';
function* fetchUser(action) {
try {
const user = yield call(Api.fetchUser, action.payload.userId);
yield put({type: 'FETCH_USER_SUCCESS', payload: { user }});
} catch (e) {
yield put({type: 'FETCH_USER_FAILED', message: e.message});
}
}
function* mySaga() {
yield takeLatest('FETCH_USER', fetchUser);
}
export default mySaga;在此示例中,我们使用 takeLatest 这个函数指定了每次只接收最新的请求。 我们使用 call 方法来提供一个从 API 获取用户数据的异步函数,并使用 put 方法来触发应用程序状态的更新。
示例 3:任务取消
使用 Redux-Saga,我们可以容易地取消正在进行的任务。 以下代码显示了如何在 Redux 中执行此操作。
// www.javascriptcn.com code example
import { take, race, call, put, cancel } from 'redux-saga/effects';
function* pollData() {
while(true) {
yield call(delay, 1000); // Our delay function returns a promise
const { stop, data } = yield race({
data: call(Api.getData),
stop: take('STOP_POLLING')
});
if (!stop) {
yield put({type: 'DATA_RECEIVED', data});
} else {
console.log('Polling stopped!');
return;
}
}
}
function* watcher() {
while(true) {
yield take('START_POLLING');
const pollTask = yield fork(pollData);
yield take('STOP_POLLING');
yield cancel(pollTask);
}
}
export default watcher;在此示例中,pollData 函数是一个无限循环,每秒调用一次 Api.getData 函数。 然后,通过使用 race 方法,该函数与 STOP_POLLING 操作进行竞争。 如果 STOP_POLLING 操作获胜,pollData 函数将通过取消任务来停止。
示例 4:事件通知
以下代码显示了在 Redux-Saga 中实现 eventBus 模式的示例。
// www.javascriptcn.com code example
import { eventChannel } from 'redux-saga';
import { takeEvery, call, put } from 'redux-saga/effects';
const sockets = {};
function createSocketChannel(socket) {
return eventChannel((emit) => {
socket.onmessage = (event) => {
emit(event);
};
return () => {
socket.close();
};
});
}
function* readFromSocket(action) {
const { socketName, message } = action.payload;
let socket = sockets[socketName];
if (!socket) {
socket = new WebSocket(`ws://${socketName}`);
sockets[socketName] = socket;
}
const socketChannel = yield call(createSocketChannel, socket);
while (true) {
const message = yield take(socketChannel);
yield put({ type: 'MESSAGE_RECEIVED', payload: { message } });
}
}
function* mySaga() {
yield takeEvery('SUBSCRIBE_TO_SOCKET', readFromSocket);
}
export default mySaga;在此示例中,我们创建了一个 eventChannel 通道,并将其传递给 WebSocket 的 onmessage 回调函数。 然后,在 while 循环中,我们使用 take 方法监听通道上的事件,并使用 put 方法将数据传递回 Redux,从而更新应用程序状态。
总结
本文提供了一个关于如何使用 Redux-Saga 中间件的实例。 我们讨论了异步调用以及如何处理诸如定时器,WebSockets 和 AJAX 调用等场景。 我们也学习了 Redux-Saga 任务的取消和事件通知。 Redux-Saga 可以使编写异步逻辑变得更加轻松和可读,请尝试在您的下一个 Redux 项目中使用它!
Source: FunTeaLearn,Please indicate the source for reprints https://funteas.com/post/648ece3248841e9894d38421