我见过 sagas 以 3 种方式监听 Action :
<强>1。 while(true) take()
function* onUserDetailsRequest() {
while(true) {
const { userId } = yield take(USER_DETAILS_REQUESTED);
const response = yield call(fetchUserDetails, userId);
put(USER_DETAILS_RECEIVED, response);
}
}
<强>2。 while(take())
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()
function* onUserDetailsRequest() {
yield takeEvery(USER_DETAILS_REQUESTED, function* (action) {
const { userId } = action;
const response = yield call(fetchUserDetails, userId);
put(USER_DETAILS_RECEIVED, response);
}
}
各自的优缺点是什么?在哪些情况下我们应该使用一个而不是另一个?
强>强>强>最佳答案
用代码澄清@AlexM的答案。
猫测试.js
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运行上面的代码会输出
{ type: 'testTake' }
{ type: 'testTakeEvery' }
{ type: 'testTakeEvery' }
{ type: 'testTakeWithFork' }
{ type: 'testTakeWithFork' }
你看出区别了吗? takeSaga 的任务在调度第二个 testTake 操作时处于休眠状态,因此 takeSaga 只是忽略了第二个 testTake 操作。但是,对于 takeEverySaga 和 takeSagaWithFork,每次都会 fork 一个新任务
它接收到一个testTakeEvery Action ,所以他们在自己的任务“线程”中休眠,因此不会错过新的 Action 。因此,takeEvery 本质上与 while(true)+take+fork 相同。
关于javascript - 在 saga : `while(true) take()` vs `while(take())` vs. `takeEvery()` 中监听 Action 的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47909392/
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
在railstutorial中,作者为什么选择使用这个(代码list10.25):http://ruby.railstutorial.org/chapters/updating-showing-and-deleting-usersnamespace:dbdodesc"Filldatabasewithsampledata"task:populate=>:environmentdoRake::Task['db:reset'].invokeUser.create!(:name=>"ExampleUser",:email=>"example@railstutorial.org",:passwo
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak
我有一个rubyonrails应用程序。我按照facebook的说明添加了一个像素。但是,要跟踪转化,Facebook要求您将页面置于达到预期结果时出现的转化中。即,如果我想显示客户已注册,我会将您注册后转到的页面作为成功对象进行跟踪。我的问题是,当客户注册时,在我的应用程序中没有登陆页面。该应用程序将用户带回主页。它在主页上显示了一条消息,所以我想看看是否有一种方法可以跟踪来自Controller操作而不是实际页面的转化。我需要计数的Action没有页面,它们是ControllerAction。是否有任何人都知道的关于如何执行此操作的gem、文档或最佳实践?这是进入布局文件的像素
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
让多条路线去同一条路的最优雅的方式是什么ControllerAction?我有:get'dashboard',to:'dashboard#index'get'dashboard/pending',to:'dashboard#index'get'dashboard/live',to:'dashboard#index'get'dashboard/sold',to:'dashboard#index'这很丑陋。有什么“更优雅”的建议吗?一个类轮的奖励积分。 最佳答案 为什么不只有一个路由和一个Controller操作,并根据传递给它的参数来
我认为我的问题最好用一个例子来描述。假设我有一个名为“Thing”的简单模型,它有一些简单数据类型的属性。像...Thing-foo:string-goo:string-bar:int这并不难。数据库表将包含具有这三个属性的三列,我可以使用@thing.foo或@thing.bar之类的东西访问它们。但我要解决的问题是当“foo”或“goo”不再包含在简单数据类型中时会发生什么?假设foo和goo代表相同类型的对象。也就是说,它们都是“Whazit”的实例,只是数据不同。所以现在事情可能看起来像这样......Thing-bar:int但是现在有一个新的模型叫做“Whazit”,看起来
给定一个nxmbool数组:[[true,true,false],[false,true,true],[false,true,true]]有什么简单的方法可以返回“该列中有多少个true?”结果应该是[1,3,2] 最佳答案 使用转置得到一个数组,其中每个子数组代表一列,然后将每一列映射到其中的true数:arr.transpose.map{|subarr|subarr.count(true)}这是一个带有inject的版本,应该在1.8.6上运行,没有任何依赖:arr.transpose.map{|subarr|subarr.in
我有一个问题。我想从另一个ruby脚本运行一个ruby脚本并捕获它的输出信息,同时让它也输出到屏幕。亚军#!/usr/bin/envrubyprint"Enteryourpassword:"password=gets.chompputs"Hereisyourpassword:#{password}"我运行的脚本文件:开始.rboutput=`runner`putsoutput.match(/Hereisyour(password:.*)/).captures[0].to_s正如您在此处看到的那样,存在问题。在start.rb的第一行,屏幕是空的。我在运行程序中看不到“输入您的密