欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React開發(fā)進(jìn)階redux saga使用原理詳解

 更新時(shí)間:2022年11月28日 14:43:22   作者:空山與新雨  
這篇文章主要為大家介紹了React開發(fā)進(jìn)階redux saga使用原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

工作中使用了redux-saga這個(gè)redux中間件,如果不明白內(nèi)部原理使用起來(lái)會(huì)讓人摸不著頭腦,閱讀源碼后特意對(duì)其原理做下總結(jié)。

redux的特點(diǎn)

  • 一個(gè)標(biāo)準(zhǔn)、管理應(yīng)用副作用的redux中間件
  • 實(shí)現(xiàn)切面編程方式
  • 聲明式的編寫方式

訂閱發(fā)布的設(shè)計(jì)模式

優(yōu)點(diǎn):

  • 把異步操作轉(zhuǎn)移到單獨(dú) saga文件中,而不是糅雜在action或者component中;
  • dispatch的參數(shù)保持為純粹的action而不是thunk function;
  • 大量的saga輔助函數(shù)和effect創(chuàng)建器減少了開發(fā)者的開發(fā)成本;
  • 靈活的串行或并行能夠?qū)崿F(xiàn)復(fù)雜的異步流程。

分析原理

先舉個(gè)實(shí)踐的例子

import { createStore, applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga';
import thunk from 'redux-thunk';
import { put, takeEvery, delay, call, select } from 'redux-saga/effects';
const reducer = (state = 0, action) => {
  switch (action.type) {
    case 'put':
      return state + action.payload;
    default:
      return state;
  }
};
const sagaMiddleware = createSagaMiddleware()
export const store = createStore(reducer, applyMiddleware(sagaMiddleware, thunk));
function* main() {
  // 工具函數(shù) delay 阻塞1s
  var start = Date.now();
  yield delay(1000);
  console.log(Date.now() - start);// 1秒多
  // put 類似于 dispatch
  yield put({ type: 'put' , payload:10});
  // takeEvery 不阻塞程序
  yield takeEvery('takeEvery111', function ({ type, payload }) {
    console.log('takeEvery', type, payload); // yield put({ type: 'takeEvery111' , payload:10}); 觸發(fā)
  });
  // select 獲取state中的數(shù)據(jù)
  const state = yield select((state) => state);
  console.log(state); // 10
  // call 阻塞程序
  yield call(function* () { // 阻塞
    yield delay(1000);
  });
  console.log(Date.now() - start);// 2秒多
  yield put({ type: 'takeEvery111' , payload:10});
}
sagaMiddleware.run(main);

依次打印出如下結(jié)果:

1001
10
2004
takeEvery takeEvery111 10

1. 自動(dòng)執(zhí)行Generator

從執(zhí)行結(jié)果來(lái)看,這個(gè)main函數(shù)能自動(dòng)按順序執(zhí)行說(shuō)明在redux-saga的程序代碼中有自動(dòng)執(zhí)行g(shù)en的機(jī)制,其實(shí)源碼就是./internal/proc.js文件中,通過(guò)函數(shù)之間循環(huán)調(diào)用的方式執(zhí)行這個(gè)gen函數(shù)。

這樣的自動(dòng)執(zhí)行機(jī)制在generator中是比較常見的,比如co模塊就具有這樣的功能,其實(shí)現(xiàn)巧妙卻不復(fù)雜,如下例子:

function makePromisify(source) {
    if (source.then && typeof source.then === "function") return source
    return Promise.resolve(source)
}
function run(generatorFunc) {
    let it = generatorFunc()
    let result = it.next()
    return new Promise((resolve, reject) => {
        const next = function (result) {
            if (result.done) {
                resolve(result.value)
            }
            //保證返回的是一個(gè)promise
            result.value = makePromisify(result.value)
            result.value.then(res => {
                //將promise的返回值res傳入iterator迭代器的next方法中,作為yield后面表達(dá)式的返回值
                //it.next將停止的yield繼續(xù)執(zhí)行到下一個(gè)yield,返回的result是一個(gè)value,done屬性組成的對(duì)象
                let result = it.next(res)
                //遞歸執(zhí)行next函數(shù)
                next(result)
            }).catch(err => {
                reject(err)
            })
        }
        next(result)
    })
}

2. 發(fā)布訂閱模式

我們看到takeEvery是可以攔截到{type: 'takeEvery111'}這個(gè)action,說(shuō)明在redux-saga內(nèi)部有類似發(fā)布訂閱on/trigger這樣的機(jī)制,通過(guò)閱讀源碼我們發(fā)現(xiàn),內(nèi)部通過(guò)channel這個(gè)東西來(lái)做發(fā)布訂閱的處理;在./internal/channel.js就有這樣的源碼:

put(input) {
  const takers = (currentTakers = nextTakers)
  for (let i = 0, len = takers.length; i < len; i++) {
    const taker = takers[i]
    // 如果take匹配到, 執(zhí)行它
    if (taker[MATCH](input)) {
      taker.cancel()
      taker(input) // 發(fā)布
    }
  }
},
take(cb, matcher = matchers.wildcard) {
  cb[MATCH] = matcher
  ensureCanMutateNextTakers()
  nextTakers.push(cb) // 訂閱
},

3. put, takeEvery, delay, call返回effect

put執(zhí)行并不是直接dispatch一個(gè)action,而是通過(guò)yield向redux-saga內(nèi)部傳遞參數(shù)(這個(gè)參數(shù)在redux-saga中叫effect),內(nèi)部根據(jù)這個(gè)參數(shù)決定具體的執(zhí)行內(nèi)容。

在源碼中put、fork、call 等是通過(guò) makeEffect 創(chuàng)建了一系列 effect,這個(gè) effect 是一個(gè)普通的 js 對(duì)象,上面掛載了一些相關(guān)的信息,并且把這個(gè)effect yield到內(nèi)部的runEffejct中,然后根據(jù)type字段決定真正需要執(zhí)行的程序過(guò)程。

const makeEffect = (type, payload) => ({
  [IO]: true,
  combinator: false,
  type,
  payload,
});

總結(jié)

redux-saga還有許多要探索的地方,比如channel、狀態(tài)機(jī)的應(yīng)用、任務(wù)隊(duì)列,等。。。更多關(guān)于React進(jìn)階redux saga原理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 在react中使用windicss的問(wèn)題

    在react中使用windicss的問(wèn)題

    這篇文章主要介紹了在react中使用windicss的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • React render核心階段深入探究穿插scheduler與reconciler

    React render核心階段深入探究穿插scheduler與reconciler

    這篇文章主要介紹了React render核心階段穿插scheduler與reconciler,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-11-11
  • React-hooks中的useEffect使用步驟

    React-hooks中的useEffect使用步驟

    這篇文章主要介紹了React-hooks中的useEffect,對(duì)于React組件來(lái)說(shuō),主作用是根據(jù)數(shù)據(jù)(state/props)渲染UI,除此之外都是副作用(比如手動(dòng)修改DOM、發(fā)送ajax請(qǐng)求),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2022-05-05
  • React中使用UEditor百度富文本的方法

    React中使用UEditor百度富文本的方法

    這篇文章主要介紹了React中使用UEditor的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • react中ref獲取dom或者組件的實(shí)現(xiàn)方法

    react中ref獲取dom或者組件的實(shí)現(xiàn)方法

    這篇文章主要介紹了react中ref獲取dom或者組件的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • react中setState的執(zhí)行機(jī)制詳解

    react中setState的執(zhí)行機(jī)制詳解

    setState() 的執(zhí)行機(jī)制包括狀態(tài)合并、批量更新、異步更新、虛擬 DOM 比較和渲染組件等步驟,這樣可以提高性能并優(yōu)化渲染過(guò)程,這篇文章主要介紹了react中的setState的執(zhí)行機(jī)制,需要的朋友可以參考下
    2023-10-10
  • react.js 獲取真實(shí)的DOM節(jié)點(diǎn)實(shí)例(必看)

    react.js 獲取真實(shí)的DOM節(jié)點(diǎn)實(shí)例(必看)

    下面小編就為大家?guī)?lái)一篇react.js 獲取真實(shí)的DOM節(jié)點(diǎn)實(shí)例(必看)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-04-04
  • React項(xiàng)目搭建與Echarts工具使用詳解

    React項(xiàng)目搭建與Echarts工具使用詳解

    這篇文章主要介紹了React項(xiàng)目搭建與Echarts工具使用詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • 淺談React的最大亮點(diǎn)之虛擬DOM

    淺談React的最大亮點(diǎn)之虛擬DOM

    這篇文章主要介紹了淺談React的最大亮點(diǎn)之虛擬DOM,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • React受控組件與非受控組件詳細(xì)介紹

    React受控組件與非受控組件詳細(xì)介紹

    具體來(lái)說(shuō)這是一種react非受控組件,其狀態(tài)是在input的react內(nèi)部控制,不受調(diào)用者控制??梢允褂檬芸亟M件來(lái)實(shí)現(xiàn)。下面就說(shuō)說(shuō)這個(gè)React中的受控組件與非受控組件的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2022-09-09

最新評(píng)論