成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為什么 Redux-Saga 不能用 Async Await 實(shí)現(xiàn)

開發(fā) 前端
當(dāng) generator 返回的值都是 Promise,那么執(zhí)行 Promise 以后,只有 resolve 和 reject 兩種結(jié)果,這個執(zhí)行器就很固定,那自然可以寫一個通用的執(zhí)行器來自動調(diào)用 next、throw 和 return。

[[427072]]

今天群里有個小伙伴問了個問題

為什么 saga 不能用 async await 來實(shí)現(xiàn)呢?

想必開始接觸 redux-saga 的同學(xué)都有這個疑問,為啥為要用 generator 的寫法,用 async await 行不行。

  1. import { put, call } from 'redux-saga/effects' 
  2. import { loginService } from '../service/request' 
  3.  
  4. function* login(action) { 
  5.     try { 
  6.         const loginInfo = yield call(loginService, action.account) 
  7.         yield put({ type: 'loginSuccess', loginInfo }) 
  8.     } catch (error) { 
  9.         yield put({ type: 'loginFail', error }) 
  10.     } 

這個問題我剛開始用 saga 的時候也想問,但后來了解了 saga 的原理就想明白了。

下面我們就來探究一下。

saga 原理

我們從組件把 action 發(fā)給 store,這個過程是同步的。

但是有一些異步的過程加在哪里呢?中間件。

redux saga 會先把 action 直接透傳給 store,這個過程是同步的。

然后再傳遞一份給 watcher saga,看一下是否是被監(jiān)聽的 action,如果是交給 worker saga 來處理,worker saga 處理的過程中可以 put 新的 action 到 store,這個過程是異步的。

這就是 redux-saga 的原理,原理上還是比較簡單的,亮點(diǎn)在于異步過程的組織上,也就是 generator 上。

為什么說用 generator 來組織異步過程是 redux-saga 的亮點(diǎn)呢?

別急,我們先了解下什么是 generator。

generator

生成器(generator)是一個產(chǎn)生迭代器(iterator)的函數(shù),通過 yield 返回一個個值。

而迭代器是一個有 value 和 done 屬性的對象,用于順序遍歷某個集合。

我們可以調(diào)用 iterator.next 取到 yield 生成的一個個值。

也可以用 Array.from 或者展開運(yùn)算符來取,這是 iterator 的特點(diǎn)。

除了 next 方法,迭代器還有 return 和 throw 方法,就像函數(shù)里的 return 和 throw 語句一樣。

比如用 iterator.return 中止后續(xù)流程

用 iterator.throw 拋出錯誤

也就是說 generator 的執(zhí)行是要由一個執(zhí)行器來控制的,什么時候取下一個 yield 出的值,什么時候 next,什么時候 return 什么時候 throw 都是由執(zhí)行器控制。

執(zhí)行器可以通過 next、return、throw 的參數(shù)傳遞給 generator 執(zhí)行后的結(jié)果:

上面這段代碼就是一個小型 saga 了,原理就這么簡單。

那為什么 async await 不行呢?

async await

當(dāng) generator 返回的值都是 Promise,那么執(zhí)行 Promise 以后,只有 resolve 和 reject 兩種結(jié)果,這個執(zhí)行器就很固定,那自然可以寫一個通用的執(zhí)行器來自動調(diào)用 next、throw 和 return。

這個就是 async await 的原理,只不過被做成了語法糖。

async await 本質(zhì)上不過是一個 generator 的執(zhí)行器。

如果 redux-saga 用 async await 實(shí)現(xiàn),那么所有的異步邏輯都要命令式的寫在 await 后面,這樣會導(dǎo)致異步過程很難測試。所以 redux-saga 自己實(shí)現(xiàn)了一個執(zhí)行器。

再來看這段 saga 的代碼:

  1. import { put, call } from 'redux-saga/effects' 
  2. import { loginService } from '../service/request' 
  3.  
  4. function* login(action) { 
  5.     try { 
  6.         const loginInfo = yield call(loginService, action.account) 
  7.         yield put({ type: 'loginSuccess', loginInfo }) 
  8.     } catch (error) { 
  9.         yield put({ type: 'loginFail', error }) 
  10.     } 

generator 中 yield 出的不是 promise,而是一個個 effect,這個其實(shí)就是一個對象,聲明式的告訴 saga 執(zhí)行器要做什么,而不是命令式的自己實(shí)現(xiàn)。

這樣 generator 的執(zhí)行器就根據(jù)不同的 effect 做不同的實(shí)現(xiàn):

call effect 有對應(yīng)的實(shí)現(xiàn)、put effect 也有對應(yīng)的實(shí)現(xiàn),也就是說 saga 的 generator 執(zhí)行器不像 async await 那樣什么都不做,而是有自己的 runtime 在的。

這樣有什么好處呢?

  • 可以替換 saga effect 具體的執(zhí)行邏輯,易于測試。比如從請求數(shù)據(jù)換成直接返回值,連 mock 都不用了。
  • 可以內(nèi)置一系列的 saga,方便組織異步過程,比如 throttle、debounce、race 等

現(xiàn)在,我們回到最開始那個問題,redux-saga 能用 async await 實(shí)現(xiàn)么?

能,但是 async await 是一個 generator 的自動執(zhí)行器,沒有 runtime 邏輯,要命令式的把異步過程寫在 saga 里。如果自己實(shí)現(xiàn)一個 generator 執(zhí)行器,那么就可以把異步過程抽離出來,方便組織、方便測試。用 async await 實(shí)現(xiàn) saga 的話,那就失去了靈魂。

總結(jié)

redux-saga 的原理是透傳 action 到 store,然后再傳一份 aciton 到 saga 組織的異步過程,saga 分為 watcher saga 和 worker saga。watcher saga 判斷 action 是否要處理,然后交給 wroker saga 處理。

生成器 generator 是返回迭代器 iterator 的函數(shù),iterator 有 next、throw、return 等方法,需要配合一個執(zhí)行器來執(zhí)行。

async await 本質(zhì)上就是一個 generator 的自動執(zhí)行器。

用 async await 實(shí)現(xiàn) redux saga 的話,那就要開發(fā)者命令式的組織異步過程,還難以測試。

所以 redux-saga 自己實(shí)現(xiàn)了一個 generator 執(zhí)行器,自帶 runtime。generator 只要返回 effect 對象來聲明式的說明要執(zhí)行什么邏輯,然后由相應(yīng)的 effect 實(shí)現(xiàn)來執(zhí)行。

這種聲明式的思路除了易于組織異步過程外,還有非常好的可測試性。

 

generator + saga 執(zhí)行器的設(shè)計是 redux-saga 的靈魂,所以不能用 async await 來實(shí)現(xiàn)。

 

責(zé)任編輯:武曉燕 來源: 神光的編程秘籍
相關(guān)推薦

2023-09-14 13:23:42

Llama-2模型參數(shù)

2025-06-12 01:11:11

AsyncAwait函數(shù)

2022-08-31 10:14:00

JavaScript網(wǎng)絡(luò)異步性

2018-06-04 15:17:10

編程語言中文編程

2014-07-15 10:31:07

asyncawait

2016-11-22 11:08:34

asyncjavascript

2024-03-12 08:37:32

asyncawaitJavaScript

2012-07-22 15:59:42

Silverlight

2021-07-20 10:26:12

JavaScriptasyncawait

2023-10-08 10:21:11

JavaScriptAsync

2022-08-27 13:49:36

ES7promiseresolve

2023-07-28 07:31:52

JavaScriptasyncawait

2024-12-30 08:22:35

2021-06-28 07:27:43

AwaitAsync語法

2020-10-10 08:43:02

CPU不能用在手機(jī)里

2020-10-09 13:23:29

芯片電腦CPU

2024-12-23 08:00:45

2010-11-02 15:44:20

瘦客戶端

2022-06-13 07:36:47

useEffectHooks

2021-06-15 05:36:45

Gulpawaitasync
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: av在线影院| 久综合| 欧美人成在线视频 | 亚洲成人观看 | 超碰在线免费av | 欧美11一13sex性hd| 亚洲乱码国产乱码精品精98午夜 | 国产精品视频一区二区三区四蜜臂 | 国产精品高潮呻吟久久aⅴ码 | 国产亚洲精品久久久优势 | 少妇久久久 | 亚洲 中文 欧美 日韩 在线观看 | 国产一在线 | 日韩欧美一级 | 毛片在线免费 | 久久精品中文字幕 | 国产精品欧美日韩 | 激情久久久久 | 国产视频一区二区在线观看 | 国产精品视频网 | 999精品视频 | 亚洲一区二区三区四区av | 91www在线观看| 性高湖久久久久久久久 | 91原创视频在线观看 | 欧美一区二区三区在线观看 | 欧美激情a∨在线视频播放 成人免费共享视频 | 亚洲国产一区二区视频 | 欧美精品久久久久久 | 欧美精品在线一区 | 成人视屏在线观看 | 欧美成人aaa级毛片在线视频 | 精品少妇一区二区三区在线播放 | jizz中国日本| 97超在线视频 | 日韩在线免费视频 | 成人国产精品久久 | 国产1区 | 亚洲一区二区三区四区五区午夜 | 久久久久国产精品午夜一区 | 另类一区|