Git Product home page Git Product logo

redux-saga-in-chinese's Introduction

Redux Logo Landscape

redux-saga

文档版本号:1.0.0-beta

英文原版:https://redux-saga.js.org/

redux-saga 是一个用于管理应用程序 Side Effect(副作用,例如异步获取数据,访问浏览器缓存等)的 library,它的目标是让副作用管理更容易,执行更高效,测试更简单,在处理故障时更容易。

可以想像为,一个 saga 就像是应用程序中一个单独的线程,它独自负责处理副作用。 redux-saga 是一个 redux 中间件,意味着这个线程可以通过正常的 redux action 从主应用程序启动,暂停和取消,它能访问完整的 redux state,也可以 dispatch redux action。

redux-saga 使用了 ES6 的 Generator 功能,让异步的流程更易于读取,写入和测试。(如果你还不熟悉的话,这里有一些介绍性的链接 通过这样的方式,这些异步的流程看起来就像是标准同步的 Javascript 代码。(有点像 async/await,但 Generator 还有一些更棒而且我们也需要的功能)。

你可能已经用了 redux-thunk 来处理数据的读取。不同于 redux thunk,你不会再遇到回调地狱了,你可以很容易地测试异步流程并保持你的 action 是干净的。

开始

安装

$ npm install --save redux-saga

$ yarn add redux-saga

或者,你可以直接在 HTML 页面的 <script> 标签中使用提供的 UMD 构建文件。参见 本节

使用示例

假设我们有一个 UI 界面,在单击按钮时从远程服务器获取一些用户数据(为简单起见,我们只列出 action 触发代码)。

class UserComponent extends React.Component {
  ...
  onSomeButtonClicked() {
    const { userId, dispatch } = this.props
    dispatch({type: 'USER_FETCH_REQUESTED', payload: {userId}})
  }
  ...
}

这个组件 dispatch 一个 plain Object 的 action 到 Store。我们将创建一个 Saga 来监听所有的 USER_FETCH_REQUESTED action,并触发一个 API 调用获取用户数据。

sagas.js

import { call, put, takeEvery, takeLatest } from 'redux-saga/effects'
import Api from '...'

// worker Saga : 将在 USER_FETCH_REQUESTED action 被 dispatch 时调用
function* fetchUser(action) {
   try {
      const user = yield call(Api.fetchUser, action.payload.userId);
      yield put({type: "USER_FETCH_SUCCEEDED", user: user});
   } catch (e) {
      yield put({type: "USER_FETCH_FAILED", message: e.message});
   }
}

/*
  在每个 `USER_FETCH_REQUESTED` action 被 dispatch 时调用 fetchUser
  允许并发(译注:即同时处理多个相同的 action)
*/
function* mySaga() {
  yield takeEvery("USER_FETCH_REQUESTED", fetchUser);
}

/*
  也可以使用 takeLatest

  不允许并发,dispatch 一个 `USER_FETCH_REQUESTED` action 时,
  如果在这之前已经有一个 `USER_FETCH_REQUESTED` action 在处理中,
  那么处理中的 action 会被取消,只会执行当前的
*/
function* mySaga() {
  yield takeLatest("USER_FETCH_REQUESTED", fetchUser);
}

export default mySaga;

为了能跑起 Saga,我们需要使用 redux-saga 中间件将 Saga 与 Redux Store 建立连接。

main.js

import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'

import reducer from './reducers'
import mySaga from './sagas'

// create the saga middleware
const sagaMiddleware = createSagaMiddleware()
// mount it on the Store
const store = createStore(
  reducer,
  applyMiddleware(sagaMiddleware)
)

// then run the saga
sagaMiddleware.run(mySaga)

// render the application

文档

在浏览器中使用 umd 构建版本

dist/ 文件夹有一个可用的 umd redux-saga 构建文件。redux-sagaReduxSaga 挂载在全局 window 对象中。这能让你在创建 Saga 中间件时不需要使用 ES6 的 import 语法:

var sagaMiddleware = ReduxSaga.default()

umd 版本在你不使用 Webpack 或 Browserify 时相当有用。你可以从 unpkg 直接读取。

以下是可用的构建好的文件:

The runtime must be imported before redux-saga: 重要! 如果你的目标浏览器不支持 ES2015 generators,那么你必须使用转换器来编译它们(比如 babel plugin) 并提供一个有效的 runtime,比如 这个。 这个 runtime 必须在 redux-saga 之前引入:

import 'regenerator-runtime/runtime'
// then
import sagaMiddleware from 'redux-saga'

从资源构建示例

$ git clone https://github.com/redux-saga/redux-saga.git
$ cd redux-saga
$ npm install
$ npm test

以下的例子是从 Redux 仓库移植过来的(截至目前)。

计数器示例

有 3 个计数器例子。

counter-vanilla

这个例子使用了 vanilla Javascript 和 UMD 构建版本。所有资源都在 index.html 中引入。

在浏览器中打开 index.html 运行这个例子。

重要:你的浏览器必须支持 Generator。最新版本的 Chrome/Firefox/Edge 已经支持。

counter

这个例子使用了 webpack 和高阶 API takeEvery

$ npm run counter

# test sample for the generator
$ npm run test-counter

cancellable-counter

这个例子使用了低阶 API 来演示任务取消的场景。

$ npm run cancellable-counter

购物车示例

$ npm run shop

# test sample for the generator
$ npm run test-shop

异步示例

$ npm run async

# test sample for the generators
$ npm run test-async

真实项目示例(使用 webpack 的热重载)

$ npm run real-world

# sorry, no tests yet

TypeScript

Redux-Saga 与 TypeScript 配合使用需要 DOM.IterableES2015.Iterable。如果你的 targetES6,则不需要再设置,然而如果是 ES5,你将需要自己把它们加进来。 检查你的 tsconfig.json 文件和官方的 compiler options 文档。

Logo

你可以在 logo 目录 中找到不同风格的 Redux-Saga 官方 logo。

贡献者

定期更新

如果看到翻译不准确、句子不通顺的地方,欢迎随时指出。本文档翻译流程按照 ETC 翻译规范,欢迎你来一起完善。

redux-saga-in-chinese's People

Contributors

2016gx avatar cycle263 avatar ihupoo avatar imyelo avatar kanata996 avatar npmcdn-to-unpkg-bot avatar odanzhou avatar sameenzm avatar superraytin avatar xiaoqqchen avatar yi-man avatar yoyo837 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

redux-saga-in-chinese's Issues

翻译志愿者招募

如果想参与翻译某个章节,直接回复此 issue 即可,比如:

认领 高级 - 组合 Sagas

翻译流程参考 ETC 翻译规范

先查看 翻译进度,后面有 ing 标志,说明此章节已被认领。

高级-同时执行多个任务,应当为yield all([]), 缺少了all()函数调用

如题所示,在 https://redux-saga-in-chinese.js.org/docs/advanced/RunningTasksInParallel.html 中出现了这个问题,虽然此github源中的文档内容和英文原版没有出入,都是用的yield all([]), 但是在html版本的文档中并没有得到同步。

中文文档: https://redux-saga-in-chinese.js.org/docs/advanced/RunningTasksInParallel.html
此github源: https://github.com/superRaytin/redux-saga-in-chinese/tree/master/docs/advanced/RunningTasksInParallel.md

redux-saga v1.0 文档更新

redux-saga v1.0 已经正式发布了,希望中文文档也能尽快更新。相比于 1.0.0-beta,1.0 的更新内容应该不会太多。

delay 方法引用错误

文章中

import { delay } from 'redux-saga'

正确

import { delay } from "redux-saga/effects"

文档描述的歧异

文件:监听未来的action
官方文档: Using take has a subtle impact on how we write our code
中文文档翻译:使用 take 组织代码有一个小问题
当前的语境应该翻译为:使用take对我们编写代码的方式有微妙的影响(好处)

启动 saga 代码错误

按照文章的代码,启动 saga 无效,查看了官方英文原版,发现正确的代码应该如下

import rootSaga from './sagas'

const sagaMiddleware = createSagaMiddleware()

const store = createStore(reducer, applyMiddleware(sagaMiddleware))

sagaMiddleware.run(rootSaga)

最新的翻译是不是没有同步到网站上?

function* saga() {
  yield take(ACTION)              // 阻塞: 将等待 action
  yield call(ApiFn, ...args)      // 阻塞: 将等待 ApiFn (如果 ApiFn 返回一个 Promise 的话)
  yield call(otherSaga, ...args)  // 阻塞: 将等待 otherSaga 结束

  yield put(...)                   // 阻塞: 将同步发起 action (使用 Promise.then)

  const task = yield fork(otherSaga, ...args)  // 非阻塞: 将不会等待 otherSaga
  yield cancel(task)                           // 非阻塞: 将立即恢复执行
  // or
  yield join(task)                             // 阻塞: 将等待 task 结束
}

这句话:
yield put(...) // 阻塞: 将同步发起 action (使用 Promise.then)

但是我看最新的Glossary.md已经翻译过来了

function* saga() {
  yield take(ACTION)              // 阻塞: 将等待 action
  yield call(ApiFn, ...args)      // 阻塞: 将等待 ApiFn (如果 ApiFn 返回一个 Promise 的话)
  yield call(otherSaga, ...args)  // 阻塞: 将等待 otherSaga 结束

  yield put(...)                   // 非阻塞: 将同步发起 action (使用 Promise.then)
  yield put.resolve(...)                   // 阻塞

  const task = yield fork(otherSaga, ...args)  // 非阻塞: 将不会等待 otherSaga
  yield cancel(task)                           // 非阻塞: 将立即恢复执行
  // or
  yield join(task)                             // 阻塞: 将等待 task 结束
}

文档同步(v1.0.0-beta)

现在的文档版本过于老旧(基于 v0.9.5),已经无法跟上社区的步伐,现启动同步至官方最新文档的工作。

由于个人时间有限,现招募志愿者一起来完成这项工作。欢迎认领翻译任务,为 redux-saga 中文社区作出贡献,翻译工作完成后,所有贡献者将会列在本项目首页,还等什么!

贡献

志愿者必须具备一定的英语水平。如果你想成为一个志愿者,在本 issue 中留言如 认领 advanced/Channels.md,然后我会更新本 issue,在你认领的任务标注志愿者名字并@。同时招募审稿人(reviewer),目前审稿人为 @superRaytin

工作步骤:

  1. fork redux-saga-in-chinese & git clone
  2. redux-saga-in-chinese:1.0.0 基础上创建一个分支,比如 sync-advanced-channels
  3. npm i && npm run watch
  4. 翻译认领的任务,参考 ETC 翻译规范
  5. 翻译完成后,发 PR 到 redux-saga-in-chinese:1.0.0 分支
  6. 如果一切 OK,PR 会尽快被合并

TODOs

advanced

api

basics

introduction

recipes

已经完成的任务,可以到 1.0.0 分支查看

redux-saga-beginner-tutorial示例代码与原文不同

目前文档中的代码:

// ...
import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'

//...
import { helloSaga } from './sagas'

const store = createStore(
  reducer,
  applyMiddleware(createSagaMiddleware(helloSaga))
)

// rest unchanged

应该更新为:

// ...
import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'

// ...
import { helloSaga } from './sagas'

const sagaMiddleware = createSagaMiddleware()
const store = createStore(
  reducer,
  applyMiddleware(sagaMiddleware)
)
sagaMiddleware.run(helloSaga)

const action = type => store.dispatch({type})

// rest unchanged

关于副作用和异步操作之间的理解

redux-saga 是一个用于管理 Redux 应用异步操作(Side Effects。译注:直译成 “副作用” 不太通顺,所以这里译为 “异步操作” 更好理解)的中间件(又称异步 action)。

我认为此处的Side Effects应该直译为“副作用”,saga的理念并不是维护和管理异步,而是将所有“非纯(impure)”的东西从源码和逻辑两个层面上独立出来,放在一个隔离的区域内单独管理

举一个最简单的案例,document.cookie的操作很显然是同步的,但是当使用saga时,你并不会在一个action creator中直接写setCookie('myCookie', value),而是会使用dispatch({type: 'SET_COOKIE', payload: ...})交给saga进行处理,同样getCookie也会使用类似的方案,这就是saga本身的概念模型

因此,在中文翻译中将Side Effects作“异步”理解并不是准确的,也可能误导使用者不在自己的应用中将有副作用的代码完全隔离,最终变成不伦不类的模型

更新文档至最新的 redux-saga 版本

贡献指南:

  1. fork redux-saga-in-chinese & git clone
  2. master 基础上创建一个分支,比如 sync-introduction-beginner-tutorial
  3. npm i && npm run watch
  4. issues 列表查找任务,回复认领
  5. 找到具体的章节,如 docs/introduction/BeginnerTutorial.md
  6. 翻译它,参考 ETC 翻译规范
  7. 完成后,发 PR 到 0.11.0 分支
  8. 如果一切 OK,PR 会尽快被合并

Beginner Tutorial 部分代码与官方文档不一致

官方文档中的示例代码
// ...
import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'

// ...
import { helloSaga } from './sagas'

const sagaMiddleware = createSagaMiddleware()
const store = createStore(
reducer,
applyMiddleware(sagaMiddleware)
)
sagaMiddleware.run(helloSaga)

const action = type => store.dispatch({type})

// rest unchanged

翻译中的示例代码
// ...
import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'

//...
import { helloSaga } from './sagas'

const store = createStore(
reducer,
applyMiddleware(createSagaMiddleware(helloSaga))
)

// rest unchanged

使用翻译中的示例代码运行,并不能接入saga,作为新手,回去看原文才明白哪里错了,还望更新。

副作用 (side effects)

https://github.com/superRaytin/redux-saga-in-chinese/blob/master/README.md 提到:

redux-saga 是一个用于管理 Redux 应用异步操作(Side Effects。译注:直译成 “副作用” 不太通顺,所以这里译为 “异步操作” 更好理解)的中间件(又称异步 action)。 redux-saga 通过创建 Sagas 将所有的异步操作逻辑收集在一个地方集中处理,可以用来代替 redux-thunk 中间件。

關於副作用解釋成異步操作是錯的,side effects 可以是同步的。

Side effects 本身就是指「副作用」,就是無法從 return 回傳值中可觀察到的改變外部行為。這是函數式編程的基礎。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.