使用rxjs过滤和验证返回值的方法
下面是我试图弄清楚如何使用rxjs实现的场景:使用rxjs过滤和验证返回值的方法,rxjs,rxjs5,Rxjs,Rxjs5,下面是我试图弄清楚如何使用rxjs实现的场景: 从文件/数据库等加载一些元数据集。元数据中的每个元素都有一个id和其他信息,如实际数据的位置。目前,我正在应用程序开始时异步加载所有这些元数据。加载此数据后,可观察调用完成。最终,我可能会添加一个刷新功能 在应用程序稍后的某个时候,我需要根据元数据中可用的内容加载特定的数据集。我目前正尝试使用类似于fetchData(id:string[]):Observable的函数来实现这一点。这就是我不清楚如何在rxjs范式下进行的地方。我同样不确定如何使用
我已经考虑过在这里使用Rx.Subject,但从我所读到的内容来看,在rxjs范式下,这通常是不可取的。请说明在rxjs范式下,哪些方法适用于此场景。谢谢 这是我想出的解决办法。此函数创建一个Observable,该Observable依赖IBufferEvaluator来告诉它如何处理源Observable发出的每个项。它可以将项目附加到缓冲区,跳过发出的项目,清除缓冲区,将缓冲区刷新到订阅服务器,等等。如果找到更好的方法,请告诉我,特别是如果它是现成的rxjs解决方案。谢谢
import Rx from 'rxjs/Rx';
export enum BufferAction {
APPEND, /** Append the current emission to the buffer and continue **/
SKIP, /** Do nothing, ignoring the current emission if applicable **/
FLUSH, /** This will ignore the current emission, if applicable, and flush the existing buffer contents */
CLEAR, /** Clear the buffer contents. Ignore the current emission, if applicable */
COMPLETE, /** Mark the Observable as Complete. The buffer will be cleared upon completion. **/
APPEND_THEN_FLUSH, /** Append the current emission to the buffer prior to flushing it **/
APPEND_THEN_COMPLETE, /** Append the current emission to the buffer and then complete **/
CLEAR_THEN_APPEND, /** Clear the buffer contents and then append the current emission to it */
FLUSH_THEN_APPEND, /** Flush the buffer contents and then append the current emission to it */
FLUSH_THEN_COMPLETE, /** Flush the buffer contents and then mark the Observable as complete */
APPEND_FLUSH_COMPLETE /** Append the current emission, flush the buffer, and then complete */
}
export function bufferActionToString(action: BufferAction):string
{
switch(action)
{
case BufferAction.APPEND: return "APPEND";
case BufferAction.SKIP: return "SKIP";
case BufferAction.FLUSH: return "FLUSH";
case BufferAction.CLEAR: return "CLEAR";
case BufferAction.COMPLETE: return "COMPLETE";
case BufferAction.APPEND_THEN_FLUSH: return "APPEND_THEN_FLUSH";
case BufferAction.APPEND_THEN_COMPLETE: return "APPEND_THEN_COMPLETE";
case BufferAction.CLEAR_THEN_APPEND: return "CLEAR_THEN_APPEND";
case BufferAction.FLUSH_THEN_APPEND: return "FLUSH_THEN_APPEND";
case BufferAction.FLUSH_THEN_COMPLETE: return "FLUSH_THEN_COMPLETE";
case BufferAction.APPEND_FLUSH_COMPLETE: return "APPEND_FLUSH_COMPLETE";
default: return "Unrecognized Buffer Action [" + action + "]";
}
}
export interface IBufferEvaluator<T>
{
evalOnNext(next:T, buffer: T[]):BufferAction;
evalOnComplete(buffer: T[]):BufferAction;
}
/** bufferWithEval.ts
* An Operator that buffers the emissions from the source Observable. As each emission is recieved,
* it and the buffered emissions are evaluated to determine what BufferAction to APPEND. You can APPEND
* the current emission value to the end of the buffered emissions, you can FLUSH the buffered emissions
* before or after appending the current emission value, you can SKIP the current emission value and then
* (optionally) FLUSH the buffer, and you can CLEAR the buffer before or after appending the current emission.
*
* The evalOnNext and evalOnComplete are expected to return a BufferAction to indicate
* which action to take. If no evalOnNext is supplied, it will default to APPENDing each emission. The evalOnComplete
* will default to FLUSH_THEN_COMPLETE. If evalOnNext or evalOnComplete throw an exception, the Observable will emit
* the exception and cease.
*/
export function bufferWithEval<T>
( source: Rx.Observable<T>,
evaluatorFactory?: () => IBufferEvaluator<T>
) : Rx.Observable<T[]>
{
/** if no evaluatorFactory supplied, use the default evaluatorFactory **/
if(!evaluatorFactory)
{
evaluatorFactory = () => {
return {
evalOnNext : function(next: T, buffer: T[]) { return BufferAction.APPEND; },
evalOnComplete : function(buffer: T[]) { return BufferAction.FLUSH; }
};
}
}
return new Rx.Observable<T[]>((subscriber: Rx.Subscriber<T[]>) =>
{
var _buffer = new Array<T>();
var _evaluator = evaluatorFactory();
var _subscription: Rx.Subscription = null;
function append(next: T)
{
_buffer.push(next);
}
function flush()
{
try
{
subscriber.next(_buffer);
}
finally
{
// Ignore any exceptions that come from subscriber.next()
clear();
}
}
function clear()
{
_buffer = new Array<T>();
}
function next(next: T)
{
try
{
var action = _evaluator.evalOnNext(next, _buffer.slice(0));
switch(action)
{
case BufferAction.APPEND: { append(next); break; }
case BufferAction.SKIP: { break; }
case BufferAction.FLUSH: { flush(); break; }
case BufferAction.CLEAR: { clear(); break; }
case BufferAction.COMPLETE: { complete(); break; }
case BufferAction.APPEND_THEN_FLUSH: { append(next); flush(); break; }
case BufferAction.APPEND_THEN_COMPLETE: { append(next); complete(); break; }
case BufferAction.APPEND_FLUSH_COMPLETE: { append(next); flush(); complete(); break; }
case BufferAction.CLEAR_THEN_APPEND: { clear(); append(next); break; }
case BufferAction.FLUSH_THEN_APPEND: { flush(); append(next); break; }
case BufferAction.FLUSH_THEN_COMPLETE: { flush(); complete(); break; }
default: throw new Error("next(): Invalid BufferAction '" + bufferActionToString(action) + "'");
}
}
catch(e)
{
error(e);
}
}
function complete()
{
try
{
var action = _evaluator.evalOnComplete(_buffer.slice(0));
switch(action)
{
case BufferAction.FLUSH_THEN_COMPLETE:
case BufferAction.FLUSH: { flush(); }
case BufferAction.CLEAR:
case BufferAction.COMPLETE: { break; }
case BufferAction.APPEND:
case BufferAction.APPEND_THEN_FLUSH:
case BufferAction.APPEND_THEN_COMPLETE:
case BufferAction.APPEND_FLUSH_COMPLETE:
case BufferAction.SKIP:
case BufferAction.CLEAR_THEN_APPEND:
case BufferAction.FLUSH_THEN_APPEND:
default: throw new Error("complete(): Invalid BufferAction '" + bufferActionToString(action) + "'");
}
clear();
subscriber.complete();
_subscription.unsubscribe();
}
catch(e)
{
error(e);
}
}
function error(err: any)
{
try
{
subscriber.error(err);
}
finally
{
_subscription.unsubscribe();
}
}
_subscription = source.subscribe(next, error, complete);
return _subscription;
});
}
从“rxjs/Rx”导入Rx;
导出枚举缓冲区操作{
追加,/**将当前发射追加到缓冲区并继续**/
跳过,/**什么也不做,忽略当前发射(如果适用)**/
刷新,/**这将忽略当前发射(如果适用),并刷新现有缓冲区内容*/
清除,/**清除缓冲区内容。忽略当前发射(如果适用)*/
完成,/**将可观察到的标记为完成。完成后将清除缓冲区**/
APPEND_然后_FLUSH,/**在刷新前将当前发射附加到缓冲区**/
APPEND_然后_COMPLETE,/**将当前发射附加到缓冲区,然后完成**/
清除\然后\追加,/**清除缓冲区内容,然后将当前发射附加到缓冲区*/
FLUSH\u然后\u APPEND,/**刷新缓冲区内容,然后将当前发射附加到缓冲区*/
刷新,然后刷新完成,/**刷新缓冲区内容,然后将可观察内容标记为完成*/
追加\u刷新\u完成/**追加当前发射,刷新缓冲区,然后完成*/
}
导出函数bufferActionToString(操作:BufferAction):字符串
{
开关(动作)
{
case BufferAction.APPEND:返回“APPEND”;
case BufferAction.SKIP:返回“SKIP”;
case BufferAction.FLUSH:返回“FLUSH”;
case BufferAction.CLEAR:返回“CLEAR”;
case BufferAction.COMPLETE:返回“COMPLETE”;
case BufferAction.APPEND\u THEN\u FLUSH:返回“APPEND\u THEN\u FLUSH”;
case BufferAction.APPEND_THEN_COMPLETE:返回“APPEND_THEN_COMPLETE”;
case BufferAction.CLEAR\u THEN\u APPEND:返回“CLEAR\u THEN\u APPEND”;
case BufferAction.FLUSH\u THEN\u APPEND:返回“FLUSH\u THEN\u APPEND”;
case BufferAction.FLUSH\u THEN\u COMPLETE:返回“FLUSH\u THEN\u COMPLETE”;
case BufferAction.APPEND\u FLUSH\u COMPLETE:返回“APPEND\u FLUSH\u COMPLETE”;
默认值:返回“无法识别的缓冲区操作[”+操作+“]”;
}
}
导出接口IBufferator
{
evalOnNext(next:T,buffer:T[]):BufferAction;
evalOnComplete(buffer:T[]):BufferAction;
}
/**bufferWithEval.ts
*缓冲可观测源排放的操作员。每次接收到排放物时,
*对其和缓冲排放进行评估,以确定要附加的缓冲动作。您可以附加
*当前排放值到缓冲排放的末尾,可以刷新缓冲排放
*在附加当前发射值之前或之后,可以跳过当前发射值,然后
*(可选)刷新缓冲区,可以在附加当前发射之前或之后清除缓冲区。
*
*evalOnNext和evalOnComplete预计将返回一个BufferAction以指示
*采取什么行动。如果未提供evalOnNext,它将默认附加每个排放。逃亡者完成了
*将默认刷新\u,然后\u完成。如果evalOnNext或evalOnComplete抛出异常,可观察对象将发出
*例外和停止。
*/
导出函数bufferWithEval
(来源:Rx.可观测,
evaluatorFactory?:()=>iBufferActor
):Rx.可观察
{
/**如果未提供evaluatorFactory,请使用默认evaluatorFactory**/
如果(!evaluatorFactory)
{
evaluatorFactory=()=>{
返回{
evalOnNext:function(next:T,buffer:T[]){return BufferAction.APPEND;},
evalOnComplete:函数(buffer:T[]){return BufferAction.FLUSH;}
};
}
}
返回新的可观察接收((订户:接收订户)=>
{
var_buffer=新数组();
var_evaluator=evaluatorFactory();
变量订阅:Rx.subscription=null;
函数追加(下一步:T)
{
_buffer.push(下一步);