Redux-saga官方文檔知識點記錄基礎部分

整理和總結官方文檔的中文翻譯版上面對于Redux-sage的介紹
文檔地址:http://leonshi.com/redux-saga-in-chinese/index.html

概述

redux-saga 是一個用于管理Redux 應用異步操作的中間件(又稱異步 action)寡键。 redux-saga 通過創(chuàng)建 Sagas 將所有的異步操作邏輯收集在一個地方集中處理坝辫,可以用來代替 redux-thunk中間件。
   Sagas 只會在應用啟動時調用。 Sagas 可以被看作是在后臺運行的進程韭邓。Sagas 監(jiān)聽發(fā)起的 action哮内,然后決定基于這個 action 來做什么:是發(fā)起一個異步調用(比如一個 Ajax 請求)奄容,還是發(fā)起其 他的 action 到 Store康聂,甚至是調用其他的 Sagas。
   在 redux-saga 的世界里北滥,所有的任務都通用 yield Effects 來完成(譯注:Effect 可以看作是 redux-saga 的任務單元)刚操。Effects 都是簡單的 Javascript 對象,包含了要被 Saga middleware 執(zhí)行的信息(打個比方再芋,你可以看到 Redux action 其實是一個個包含執(zhí)行信息的對象)
   因為使用了 Generator菊霜,redux-saga讓你可以用同步的方式寫異步代碼

基本概念

1 Saga 輔助函數(shù)

takeEvery :允許多個 fetchData實例同時啟動济赎。在某個特定時刻占卧,我們可以啟動一個新的 fetchData任務遗菠, 盡管之前還有一個或多個 fetchData尚未結束。
   takeLatest:只允許執(zhí)行一個 fetchData任務华蜒。并且這個任務是最后被啟動的那個辙纬。 如果之前已經(jīng)有一個任務在執(zhí)行,那之前的這個任務會自動被取消叭喜。
例子:

import { takeEvery } from 'redux-saga'
function* watchFetchData() {
    yield* takeEvery('FETCH_REQUESTED', fetchData)
}```
   監(jiān)聽 FETCH_REQUESTED action 之后執(zhí)行下面的異步action 任務

import { call, put } from 'redux-saga/effects'
export function* fetchData(action) {
try {
const data = yield call(Api.fetchUser, action.payload.url);
yield put({type: "FETCH_SUCCEEDED", data});
} catch (error) {
yield put({type: "FETCH_FAILED", error});
}
}

#####2 聲明式 Effects
   我們從 Generator 里 yield 純 JavaScript 對象以表達 Saga 邏輯贺拣。 我們稱呼那些對象為 *Effect*。Effect 是一個簡單的對象捂蕴,這個對象包含了一些給 middleware 解釋執(zhí)行的信息譬涡。 你可以把 Effect 看作是發(fā)送給 middleware 的指令以執(zhí)行某些操作(調用某些異步函數(shù),發(fā)起一個 action 到 store)啥辨。
   一個 Saga 所做的實際上是組合那些所有的 Effect涡匀,共同實現(xiàn)所需的控制流。 最簡單的是只需把 yield 一個接一個地放置溉知,就可對 yield 過的 Effect 進行排序陨瘩。
   我們已經(jīng)看到,使用 Effect 諸如 call 和 put级乍,與高階 API 如 takeEvery相結合舌劳,讓我們實現(xiàn)與redux-thunk 同樣的東西, 但又有額外的易于測試的好處玫荣。
######2.1 Effect 概念是如何讓 Sagas 很容易地被測試的
   假設我們有一個監(jiān)聽 PRODUCTS_REQUESTED action 的Saga甚淡。每次匹配到 action,它會啟動一個從服務器上獲取產(chǎn)品列表的任務捅厂。
   現(xiàn)在要對這段邏輯編寫測試贯卦, 在測試過程中,執(zhí)行真正的服務是一個既不可行也不實用的方法焙贷,所以我們必須 模擬函數(shù)脸侥。也就是說,我們需要將真實的函數(shù)替換為一個假的盈厘,這個假的函數(shù)并不會真的發(fā)送 AJAX 請求而只會檢查是否使用正確的參數(shù)調用方法。模擬使測試更加困難和不可靠官边。
   實際上對這段邏輯的測試我們需要的只是保證任務 yield 一個正確的函數(shù)沸手,并且這個函數(shù)有著正確的參數(shù)。  **我們可以僅僅 yield 一條描述函數(shù)調用的信息** 
   實際中當yield 一個方法時注簿,可以使用call(fn, ...args)這個函數(shù)契吉,**call創(chuàng)建了一條描述結果的信息**,call 只是一個返回純文本對象的函數(shù)诡渴,redux-saga middleware 確保執(zhí)行函數(shù)調用并在響應被 resolve 時恢復 generator捐晶。
代碼示例

import { takeEvery } from 'redux-saga'
import Api from './path/to/api'
function* watchFetchProduts() {
yield* takeEvery('PRODUCTS_REQUESTED',fetchProducts)
}
function* fetchProducts() {
const products = yield call(Api.fetch, '/products')
}

//測試代碼
import { call } from 'redux-saga/effects'
import Api from '...'
const iterator = fetchProducts()
assert.deepEqual(
iterator.next().value, call(Api.fetch, '/products')

#####3 發(fā)起 action 到 store
   我們想發(fā)起一些action通知   
   dispatch({type:'PRODUCTS_RECEIVED', products })
           為了編寫方便測試的代碼菲语,使用Effect的概念,使用指令的方式來發(fā)起通話惑灵,**只需創(chuàng)建一個對象來指示 middleware 我們需要發(fā)起一些 action山上,然后讓 middleware 執(zhí)行真實的 dispatch。**這種方式我們就可以同樣的方式測試 Generator 的 dispatch:只需檢查 yield 后的 Effect英支,并確保它包含正確的指令佩憾。指令為put
代碼示例

import { call, put } from 'redux-saga/effects'
//...
function* fetchProducts() {
const products = yield call(Api.fetch, '/products')
// 創(chuàng)建并 yield 一個 dispatch Effect
yield put({ type: 'PRODUCTS_RECEIVED', products })
}
//測試代碼
import { call, put } from 'redux-saga/effects'
import Api from '...'
const iterator = fetchProducts()
// 期望一個 call 指令
assert.deepEqual(
iterator.next().value, call(Api.fetch, '/products'),
"fetchProducts should yield an Effect call(Api.fetch,'./products')"
)
// 創(chuàng)建一個假的響應對象
const products = {}
// 期望一個 dispatch 指令
assert.deepEqual(
iterator.next(products).value, put({ type:'PRODUCTS_RECEIVED', products }),

   "fetchProducts should yield an Effect put({ type: 'PRODUCTS_RECEIVED', products })"

)

#####4 錯誤處理
   我們可以使用熟悉的 try/catch語法在 Saga 中捕獲錯誤。
代碼示例

import Api from './path/to/api'
import { call, put } from 'redux-saga/effects'
//...
function* fetchProducts() {
try {
const products = yield call(Api.fetch, '/products')
yield put({ type: 'PRODUCTS_RECEIVED', products })
} catch(error) {
yield put({ type: 'PRODUCTS_REQUEST_FAILED', error })
}
}
//測試代碼
import { call, put } from 'redux-saga/effects'
import Api from '...'
const iterator = fetchProducts()
// 期望一個 call 指令
assert.deepEqual(
iterator.next().value, call(Api.fetch, '/products'), "fetchProducts should yield an Effect call(Api.fetch, './products')"
)
// 創(chuàng)建一個模擬的 error 對象
const error = {}
// 期望一個 dispatch 指令
assert.deepEqual(
iterator.throw(error).value, put({ type: 'PRODUCTS_REQUEST_FAILED', error }),
"fetchProducts should yield an Effect put({ type: 'PRODUCTS_REQUEST_FAILED', error })"
)
//官網(wǎng)還提供了一種捕捉 Promise 的拒絕操作干花,并將它們映射到一個錯誤字段對象妄帘,可以查閱。個人喜歡第一種錯誤處理方式

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末池凄,一起剝皮案震驚了整個濱河市抡驼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌肿仑,老刑警劉巖致盟,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異柏副,居然都是意外死亡勾邦,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門割择,熙熙樓的掌柜王于貴愁眉苦臉地迎上來眷篇,“玉大人,你說我怎么就攤上這事荔泳〗侗” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵玛歌,是天一觀的道長昧港。 經(jīng)常有香客問我,道長支子,這世上最難降的妖魔是什么创肥? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮值朋,結果婚禮上叹侄,老公的妹妹穿的比我還像新娘。我一直安慰自己昨登,他們只是感情好趾代,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著丰辣,像睡著了一般撒强。 火紅的嫁衣襯著肌膚如雪禽捆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天飘哨,我揣著相機與錄音胚想,去河邊找鬼。 笑死杖玲,一個胖子當著我的面吹牛顿仇,可吹牛的內容都是我干的。 我是一名探鬼主播摆马,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼臼闻,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了囤采?” 一聲冷哼從身側響起述呐,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蕉毯,沒想到半個月后乓搬,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡代虾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年进肯,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片棉磨。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡江掩,死狀恐怖,靈堂內的尸體忽然破棺而出乘瓤,到底是詐尸還是另有隱情环形,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布衙傀,位于F島的核電站抬吟,受9級特大地震影響,放射性物質發(fā)生泄漏统抬。R本人自食惡果不足惜火本,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望聪建。 院中可真熱鬧钙畔,春花似錦、人聲如沸妆偏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钱骂。三九已至叔锐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間见秽,已是汗流浹背愉烙。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留解取,地道東北人步责。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像禀苦,于是被迫代替她去往敵國和親蔓肯。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內容

  • 最近項目用了dva振乏,dva對于異步action的處理是用了redux-saga蔗包,故簡單學習了下redux-saga...
    笨人不能懶閱讀 2,836評論 0 5
  • redux-saga框架使用詳解及Demo教程 前面我們講解過redux框架和dva框架的基本使用,因為dva框架...
    光強_上海閱讀 22,047評論 8 46
  • Redux-saga 概述 在 redux 一文中我們有說過處理異步我們應該放在 reducer 之前慧邮,所以我們需...
    滿是裂縫的花卷閱讀 2,436評論 0 2
  • Redux-saga 概述 redux-saga是一個用于管理redux應用異步操作的中間件调限,redux-saga...
    woow_wu7閱讀 51,696評論 11 41
  • 1. redux-thunk處理副作用的缺點 1.1 redux的副作用處理 redux中的數(shù)據(jù)流大致是: UI—...
    Grace_ji閱讀 3,541評論 0 14