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

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

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

[[427072]]

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

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

想必開始接觸 redux-saga 的同學都有這個疑問,為啥為要用 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 的原理,原理上還是比較簡單的,亮點在于異步過程的組織上,也就是 generator 上。

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

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

generator

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

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

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

也可以用 Array.from 或者展開運算符來取,這是 iterator 的特點。

除了 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

當 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 實現(xiàn),那么所有的異步邏輯都要命令式的寫在 await 后面,這樣會導致異步過程很難測試。所以 redux-saga 自己實現(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,這個其實就是一個對象,聲明式的告訴 saga 執(zhí)行器要做什么,而不是命令式的自己實現(xiàn)。

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

call effect 有對應的實現(xiàn)、put effect 也有對應的實現(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 實現(xiàn)么?

能,但是 async await 是一個 generator 的自動執(zhí)行器,沒有 runtime 邏輯,要命令式的把異步過程寫在 saga 里。如果自己實現(xiàn)一個 generator 執(zhí)行器,那么就可以把異步過程抽離出來,方便組織、方便測試。用 async await 實現(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 實現(xiàn) redux saga 的話,那就要開發(fā)者命令式的組織異步過程,還難以測試。

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

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

 

generator + saga 執(zhí)行器的設計是 redux-saga 的靈魂,所以不能用 async await 來實現(xià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)絡異步性

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

2023-10-08 10:21:11

JavaScriptAsync

2021-07-20 10:26:12

JavaScriptasyncawait

2022-08-27 13:49:36

ES7promiseresolve

2023-07-28 07:31:52

JavaScriptasyncawait

2021-06-28 07:27:43

AwaitAsync語法

2024-12-30 08:22:35

2020-10-09 13:23:29

芯片電腦CPU

2020-10-10 08:43:02

CPU不能用在手機里

2024-12-23 08:00:45

2010-11-02 15:44:20

瘦客戶端

2021-06-15 05:36:45

Gulpawaitasync

2022-06-13 07:36:47

useEffectHooks
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日本xx视频免费观看 | 国产高清久久久 | 久久久久国产 | 成人在线免费视频 | 日本免费视频在线观看 | 一区二区三区久久久 | 一级片免费视频 | 在线观看视频福利 | 中文字幕欧美日韩 | 国产精品成人一区二区三区 | 91精品国产欧美一区二区成人 | 男女视频免费 | 岛国在线免费观看 | 91av视频在线观看 | 欧美视频区 | 天天综合干 | 久久久一区二区三区四区 | 色综合99 | 欧美色成人 | 亚洲视频二区 | 涩在线| 欧美高清视频在线观看 | 亚洲狠狠丁香婷婷综合久久久 | 国产精品亚洲精品日韩已方 | 亚洲精品成人在线 | av天空 | 日韩中文字幕第一页 | 黄色一级毛片免费看 | jizz在线免费观看 | 成人在线精品视频 | 欧美激情在线观看一区二区三区 | 国产成人综合久久 | 伊人精品久久久久77777 | 精品国产乱码久久久久久丨区2区 | 亚洲免费观看视频 | 亚洲在线免费观看 | 欧美精品一区二区三区视频 | k8久久久一区二区三区 | 91中文字幕在线观看 | 噜啊噜在线 | 中文字幕 亚洲一区 |