<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      太上老俊

      react系列筆記:第三記-redux-saga

      github : https://github.com/redux-saga/redux-saga

      文檔:https://redux-saga.js.org/  

       

      redux-saga:  redux中間件,旨在處理應(yīng)用中的副作用

      使用:

      import createSagaMiddleware from 'redux-saga'
      import {createStore,applyMiddleware} from 'redux'
      
      const saga = createSagaMiddleware();
      
      const store = createStore(
        reducer,
        applyMiddleware(sagaMiddleware)
      )
      sagaMiddleware.run(mysagas);
        

       

      基礎(chǔ)概念:

        saga-middleware 檢查每個被 yield 的 Effect 的類型,然后決定如何實現(xiàn)哪個 Effect。如果 Effect 類型是 PUT 那 middleware 會 dispatch 一個 action 到 Store。 如果 Effect 類型是 CALL 那么它會調(diào)用給定的函數(shù)。

      put({type: 'INCREMENT'}) // => { PUT: {type: 'INCREMENT'} }
      call(delay, 1000)        // => { CALL: {fn: delay, args: [1000]}}

      輔助函數(shù):

        takeEvery : 可以同時啟動多次任務(wù)

        takeLatest : 在一次任務(wù)未完成之前,遇到新任務(wù)將取消之前任務(wù)。

      聲明式的effect

        call:  saga通過 Generator函數(shù)實現(xiàn),在yield函數(shù)后執(zhí)行effect,其中call是用于執(zhí)行某些異步操作的。

      yield requestSome('/xxx');
      
      yield call(requestSome,'/xxx')
      //之所以用call取代上面的直接調(diào)用寫法,好處在于,
      //編寫測試代碼的時候,可以deepEqual  generator函數(shù)的next().value和call(requestSome,'/xxx'),這樣所有的effect都可以被測試,而不需要mock yield后的執(zhí)行結(jié)果

      dispatching actions:

        put : 和上面的call一樣,中間件提供put 來把action丟到中間件中去dispatch,好處同樣是便于測試

       

      高級:

      take:

        call方法可以yield一個promise,然后會阻塞generator的執(zhí)行,知道promise resolve,結(jié)果返回
        take(xxx)同理,阻塞generator直到xxx匹配的action被觸發(fā)

        由此:take(*)可以用于抓取log,take(*)會匹配任意的action觸發(fā)事件

        使用while(true){ take(/xxx/) }  可以創(chuàng)建持續(xù)的action監(jiān)聽,當然也可以根據(jù)需求,選擇性的監(jiān)聽,只需改版while(xxx)的條件就行了

      function* actionLog(){
        while(true){
          yield take('INCREMENT');
          console.log('do increment');
          yield take('DECREMENT');
          console.log('do decrement')
        }
      }
      //take可以控制action的監(jiān)聽順序,如上,會先監(jiān)聽到INCREMENT之后,才會再往下監(jiān)聽DECREMENT,完后繼續(xù)監(jiān)聽INCREMENT。這在一些順序明確的action事件里,可以將流程代碼寫在一起,
      //如login   logout  

       

      fork:

        fork和take不同,take會和call一樣阻塞代碼的執(zhí)行,知道結(jié)果返回,fork則不會,它會將任務(wù)啟動并且不阻塞代碼的執(zhí)行,

        fork會返回一個task,可以用cacel(task)來取消任務(wù)

        https://redux-saga.js.org/docs/advanced/NonBlockingCalls.html

        此文中將login 和logout作為例子,在login請求未返回來之前執(zhí)行了logout,則需要cacel未完成的login,又不能用take(login)否則阻塞logout,會在login響應(yīng)之前take不到logout。

      import { take, put, call, fork, cancel } from 'redux-saga/effects'
      
      // ...
      
      function* loginFlow() {
        while (true) {
          const {user, password} = yield take('LOGIN_REQUEST')
          // fork return a Task object
          const task = yield fork(authorize, user, password)
          const action = yield take(['LOGOUT', 'LOGIN_ERROR'])
          if (action.type === 'LOGOUT')
            yield cancel(task)
          yield call(Api.clearItem, 'token')
        }
      }
      
      
      import { take, call, put, cancelled } from 'redux-saga/effects'
      import Api from '...'
      
      function* authorize(user, password) {
        try {
          const token = yield call(Api.authorize, user, password)
          yield put({type: 'LOGIN_SUCCESS', token})
          yield call(Api.storeItem, {token})
          return token
        } catch(error) {
          yield put({type: 'LOGIN_ERROR', error})
        } finally {
          if (yield cancelled()) {
            // ... put special cancellation handling code here
          }
        }
      }

      all:

        yield表達式,可以將語句分段執(zhí)行,但如果有時候想同時執(zhí)行兩個任務(wù),則需要用到all

      import {all,call} from 'redux-saga/effect'
      
      //此處會同步執(zhí)行兩個call的任務(wù)
      const [users, repos] = yield all([
        call(fetch, '/users'),
        call(fetch, '/repos')
      ])

      race:

        和promise中的race一個概念,執(zhí)行多個任務(wù),受到響應(yīng)后則繼續(xù)執(zhí)行  

      function* fetchPostsWithTimeout() {
        const {posts, timeout} = yield race({
          posts: call(fetchApi, '/posts'),
          timeout: call(delay, 1000)
        })
      
        if (posts)
          put({type: 'POSTS_RECEIVED', posts})
        else
          put({type: 'TIMEOUT_ERROR'})
      }

      yield * 

        通過yield * xxx()來組合多個generator任務(wù)。

      組合saga:

        可以通過yield [call(task1),call(task2)...]來組合多個generator。

       

      channels:

       

      throttle:

        節(jié)流

       

      delay:

        防抖動

       

      posted on 2018-06-06 11:32  太上老俊  閱讀(2035)  評論(0)    收藏  舉報

      導(dǎo)航

      主站蜘蛛池模板: 91青青草视频在线观看| 国产在线亚州精品内射| 你懂的视频在线一区二区| 亚洲欧洲日产国无高清码图片 | 一本色道久久综合亚洲精品| 国产精品亚洲综合色区丝瓜| 日本道播放一区二区三区| 久久视频这里只精品| 久久精品道一区二区三区| 亚洲精品一区二区天堂| 亚洲av无码之国产精品网址蜜芽| 国产一区一一区高清不卡| 国产成人a在线观看视频| 日韩人妻少妇一区二区三区| 男女啪啪高潮激烈免费版| 久青草国产综合视频在线| 亚洲成av人片无码天堂下载| 亚洲第一成人网站| 精品人妻伦一二二区久久| 东方av四虎在线观看| 人妻人人澡人人添人人爽| 国产免费午夜福利在线观看| 亚洲无av在线中文字幕| 欧美丰满熟妇xxxx性| 无码乱人伦一区二区亚洲| 爱性久久久久久久久| 达日县| 欧美一区二区三区成人久久片| 亚洲色大成成人网站久久| 亚洲成在人线在线播放无码| 日韩女同一区二区三区久久| a片免费视频在线观看| 日韩人妻不卡一区二区三区| 亚洲欧美自偷自拍视频图片| 国产精品一区二区蜜臀av| 西西444www高清大胆| 麻豆蜜桃av蜜臀av色欲av| 国产成人一区二区不卡| 国产精品一码二码三码| 国产精品爽爽久久久久久竹菊| 国产一区精品综亚洲av|