首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >倾听传奇中行动的最佳方式:‘`while(true) take()’vs‘`while(`while(())’vs‘`while(`while())’vs‘`takeEvery()’

倾听传奇中行动的最佳方式:‘`while(true) take()’vs‘`while(`while(())’vs‘`while(`while())’vs‘`takeEvery()’
EN

Stack Overflow用户
提问于 2017-12-20 15:25:35
回答 1查看 8.2K关注 0票数 16

我见过萨迦以三种方式聆听行动:

1.同时(真)采取()

代码语言:javascript
复制
function* onUserDetailsRequest() {
  while(true) {
    const { userId } = yield take(USER_DETAILS_REQUESTED);
    const response = yield call(fetchUserDetails, userId);
    put(USER_DETAILS_RECEIVED, response);
  }
}    

2.同时(采取())

代码语言:javascript
复制
function* onUserDetailsRequest() {
  while(yield take(USER_DETAILS_REQUESTED)) {
    const userId = yield select(userSelectorFn);
    const response = yield call(fetchUserDetails, userId);
    put(USER_DETAILS_RECEIVED, response);
  }
}    

3. takeEvery()

代码语言:javascript
复制
function* onUserDetailsRequest() {
  yield takeEvery(USER_DETAILS_REQUESTED, function* (action) {
    const { userId } = action;
    const response = yield call(fetchUserDetails, userId);
    put(USER_DETAILS_RECEIVED, response);
  }
}

每种方法的优缺点是什么?在什么情况下,我们应该使用一个而不是另一个呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-21 09:17:29

用代码清除@AlexM的答案。

cat test.js

代码语言:javascript
复制
const { createStore, applyMiddleware } =require('redux')
const createSagaMiddleware =require('redux-saga').default
const { takeEvery ,take,fork}=require('redux-saga/effects') 
const {delay} =require('redux-saga')
const sagaMiddleware = createSagaMiddleware()
const reducer=(state=[],action)=>{return [...state,action.type];}
const store = createStore(
    reducer,
    applyMiddleware(sagaMiddleware)
)
function* takeSaga() {
  while(true){
    const action=yield take('testTake')
    console.log(action)
    yield delay(1000)
  }
}

function* takeEverySaga() {
    yield takeEvery('testTakeEvery',function* (action){
        console.log(action)
        yield delay(1000)
    })
}

function* takeSagaWithFork() {
    while(true){
      const action=yield take('testTakeWithFork')
      yield fork(function*(){
        console.log(action)
        yield delay(1000)
      })
    }
}

sagaMiddleware.run(takeSaga)
sagaMiddleware.run(takeEverySaga)
sagaMiddleware.run(takeSagaWithFork)

const main=async ()=>{
    store.dispatch({type: 'testTake'})
    store.dispatch({type: 'testTake'})
    store.dispatch({type: 'testTakeEvery'})
    store.dispatch({type: 'testTakeEvery'})
    store.dispatch({type: 'testTakeWithFork'})
    store.dispatch({type: 'testTakeWithFork'})
}

main();

使用node test.js运行上述代码将输出

代码语言:javascript
复制
{ type: 'testTake' }
{ type: 'testTakeEvery' }
{ type: 'testTakeEvery' }
{ type: 'testTakeWithFork' }
{ type: 'testTakeWithFork' }

你看到区别了吗?takeSaga的任务是在第二个testTake操作发出时休眠,因此takeSaga只是忽略了第二个testTake操作。然而,对于takeEverySagatakeSagaWithFork来说,每次收到testTakeEvery操作时都会分叉一个新任务,因此他们在自己的任务“线程”中睡觉,因此不会错过新的操作。因此,while(true)+take+fork.与takeEvery本质上是相同的。

票数 23
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47909392

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档