- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个任务流,它将排队直到使用 .zip()
运算符触发信号 Subject。信号主题订阅当前正在运行的任务。我也在尝试观察任务的进度排放。
我尝试做的是使用 .publish()
多播任务 Observable 以便我可以允许信号 Subject 订阅 .last()
任务的排放导致出队并订阅任务的一般进度排放。
这似乎有效。但是,每当我查看打印出来的内容时,我的 Observable 工厂似乎都被每个 .subscribe()
调用调用,即使我使用了 .publish()
。我误解了多播的工作原理吗?我相信 .publish()
ed Observable 将与工厂一起创建,并且将共享单个实例,但直到 .connect()
被调用为止。
注意调用 tasker
的 .defer()
。
"use strict";
const {
Observable,
Subject,
BehaviorSubject
} = Rx;
// How often to increase project in a task
const INTERVAL_TIME = 200;
// Keep track of how many tasks we have
let TASK_ID = 0;
// Easy way to print out observers
function easyObserver(prefix = "Observer") {
return {
next: data => console.log(`[${prefix}][next]: ${data}`),
error: err => console.error(`[${prefix}][error] ${err}`),
complete: () => console.log(`[${prefix}][complete] Complete`)
};
}
// Simulate async task
function tasker(name = "", id = TASK_ID++) {
console.log(`tasker called for ${id}`);
let progress = 0;
const progress$ = new BehaviorSubject(`Task[${name||id}][${progress}%]`);
console.log(`Task[${name||id}][started]`);
let interval = setInterval(() => {
progress = (progress + (Math.random() * 50));
if (progress >= 100) {
progress = 100;
clearInterval(interval);
progress$.next(`Task[${name||id}][${progress}%]`);
progress$.complete();
return;
}
progress$.next(`Task[${name||id}][${progress}%]`);
}, INTERVAL_TIME);
return progress$.asObservable();
}
// Create a signal subject that will tell the queue when to next
const dequeueSignal = new BehaviorSubject();
// Make some tasks
const tasks$ = Observable
.range(0, 3);
// Queue tasks until signal tells us to emit the next task
const queuedTasks$ = Observable
.zip(tasks$, dequeueSignal, (i, s) => i);
// Create task observables
const mcQueuedTasks$ = queuedTasks$
.map(task => Observable.defer(() => tasker(`MyTask${task}`)))
.publish();
// Print out the task progress
const progressSubscription = mcQueuedTasks$
.switchMap(task => task)
.subscribe(easyObserver("queuedTasks$"));
// Cause the signal subject to trigger the next task
const taskCompleteSubscription = mcQueuedTasks$
.switchMap(task => task.last())
.delay(500)
.subscribe(dequeueSignal);
// Kick everything off
mcQueuedTasks$.connect();
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.js"></script>
请注意您是如何看到多次调用 tasker 的,这行 tasker called for N
并且调用了工厂的主体。然而,在任何进度排放发生之前,tasker()
将使用下一个 TASK_ID
再次调用。输出似乎是正确的,因为 Task[MyTask0]
不会跳过任何索引,只会跳过 TASK_ID
。
tasker called for 0
Task[MyTask0][started]
[queuedTasks$][next]: Task[MyTask0][0%]
tasker called for 1
Task[MyTask0][started]
[queuedTasks$][next]: Task[MyTask0][20.688413934455674%]
[queuedTasks$][next]: Task[MyTask0][32.928520335195564%]
[queuedTasks$][next]: Task[MyTask0][42.58361384849108%]
[queuedTasks$][next]: Task[MyTask0][73.1297043008671%]
[queuedTasks$][next]: Task[MyTask0][100%]
tasker called for 2
Task[MyTask1][started]
[queuedTasks$][next]: Task[MyTask1][0%]
tasker called for 3
Task[MyTask1][started]
[queuedTasks$][next]: Task[MyTask1][37.16513927245511%]
[queuedTasks$][next]: Task[MyTask1][47.27771448102375%]
[queuedTasks$][next]: Task[MyTask1][60.45983311604027%]
[queuedTasks$][next]: Task[MyTask1][100%]
tasker called for 4
Task[MyTask2][started]
[queuedTasks$][next]: Task[MyTask2][0%]
tasker called for 5
Task[MyTask2][started]
[queuedTasks$][next]: Task[MyTask2][32.421275902708544%]
[queuedTasks$][next]: Task[MyTask2][41.30332084025583%]
[queuedTasks$][next]: Task[MyTask2][77.44113197852694%]
[queuedTasks$][next]: Task[MyTask2][100%]
[queuedTasks$][complete] Complete
最佳答案
看起来 Observable.defer
在此函数中是不必要的:
// Create task observables
const mcQueuedTasks$ = queuedTasks$
.map(task => Observable.defer(() => tasker(`MyTask${task}`)))
.publish();
The Defer operator waits until an observer subscribes to it, and then it generates an Observable, typically with an Observable factory function. It does this afresh for each subscriber, so although each subscriber may think it is subscribing to the same Observable, in fact each subscriber gets its own individual sequence.
你已经在这里创建了一个 Observable:
// Make some tasks
const tasks$ = Observable
.range(0, 3);
在 map
循环中,您正在为每个任务创建一个额外的 Observable...
去掉 Observable.defer
这样函数看起来像这样:
// Create task observables
const mcQueuedTasks$ = queuedTasks$
.map(task => tasker(`MyTask${task}`))
.publish();
片段:
"use strict";
const {
Observable,
Subject,
BehaviorSubject
} = Rx;
// How often to increase project in a task
const INTERVAL_TIME = 200;
// Keep track of how many tasks we have
let TASK_ID = 0;
// Easy way to print out observers
function easyObserver(prefix = "Observer") {
return {
next: data => console.log(`[${prefix}][next]: ${data}`),
error: err => console.error(`[${prefix}][error] ${err}`),
complete: () => console.log(`[${prefix}][complete] Complete`)
};
}
// Simulate async task
function tasker(name = "", id = TASK_ID++) {
console.log(`tasker called for ${id}`);
let progress = 0;
const progress$ = new BehaviorSubject(`Task[${name||id}][${progress}%]`);
console.log(`Task[${name||id}][started]`);
let interval = setInterval(() => {
progress = (progress + (Math.random() * 50));
if (progress >= 100) {
progress = 100;
clearInterval(interval);
progress$.next(`Task[${name||id}][${progress}%]`);
progress$.complete();
return;
}
progress$.next(`Task[${name||id}][${progress}%]`);
}, INTERVAL_TIME);
return progress$.asObservable();
}
// Create a signal subject that will tell the queue when to next
const dequeueSignal = new BehaviorSubject();
// Make some tasks
const tasks$ = Observable
.range(0, 3);
// Queue tasks until signal tells us to emit the next task
const queuedTasks$ = Observable
.zip(tasks$, dequeueSignal, (i, s) => i);
// Create task observables
const mcQueuedTasks$ = queuedTasks$
.map(task => tasker(`MyTask${task}`))
.publish();
// Print out the task progress
const progressSubscription = mcQueuedTasks$
.switchMap(task => task)
.subscribe(easyObserver("queuedTasks$"));
// Cause the signal subject to trigger the next task
const taskCompleteSubscription = mcQueuedTasks$
.switchMap(task => task.last())
.delay(500)
.subscribe(dequeueSignal);
// Kick everything off
mcQueuedTasks$.connect();
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.js"></script>
希望对您有所帮助。
关于javascript - 为什么我发布的延迟 Observable 工厂被多次调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48175350/
我应该执行以下操作: 可能通过服务/工厂,使用 $q(异步)查询 API 以获取大型名称数据集 有另一个服务(也是异步的),它应该只返回上述工厂的元素,如果它们与某个字符串(搜索字段)匹配。目的是缩小
我有一个通用的基类。我有一个实现基类的具体类。 我将如何创建工厂类/方法来交付不同类型的具体类? 举个例子: public class ReceiverBase where T : IInte
我正在查看以下链接中的 Ninject Factory 扩展: http://www.planetgeek.ch/2011/12/31/ninject-extensions-factory-intro
工厂、提供商和服务这三个术语之间有什么区别? 刚刚了解 NHibernate 及其存储库模式(POCO 类等)。 最佳答案 工厂:通过将一堆位组合在一起或基于某种上下文选择类型来组装类 Provide
使用CGLIB我可以做到 final var enhancer = new Enhancer(); enhancer.setUseCache(false); enhancer.setSuperclas
我试图在 Kotlin 中使用伴随对象工厂方法(相当于 Java 中的静态工厂方法)创建一个嵌套内部类。这是我的代码的简化版本。 class OuterClass { var myData:L
我正在为我的大学做一个项目,但遇到了问题。 基本上,该项目由一个客户端-服务器应用程序组成,我想创建一个用于通信的 Packet 类。数据包由 header 和主体组成。现在问题来了。我可以有一些不同
这个问题在这里已经有了答案: Why doesn't polymorphism work without pointers/references? (6 个答案) What is object sl
我正在制作一个套接字工厂。我希望每个外部应用程序都使用 Socket 类的接口(interface),它是几个类(ServerSocketTCP、ClientSocketTCP、ServerSocke
我是 angularjs 的新手,我正在尝试创建一个小型电影数据库。这是我第一次使用工厂,我想确保这是正确的方法,以及如何在另一个功能中使用这个工厂,如下所示? 我希望这个工厂只运行一次,这样我就可以
这个问题在这里已经有了答案: Java inner class and static nested class (28 个答案) 关闭 5 年前。 public class DataFactory
我看过很多关于 C++ 工厂的帖子,但到目前为止我还没有看到解决我的问题的解决方案。 (虽然我可能遗漏了一些东西。) 示例控制台应用程序: #include #include #include
这是一个简单的 C++ 项目,有 2 种设计模式:单例和工厂,sigleton 也是一个模板化类,一个接口(interface) (IHash) 和一个类 (Hash1)。一个简单的工厂类 (Hash
这个问题类似于Factory and generics ,并且可能有相同的答案,但它是不同的。我有一个通用基类,它将由完全独立的 JAR 中的类进行扩展。所述 JAR 应该能够在不更改任何其他代码的情
问题是我需要为传递的类创建一个新实例 有没有办法重写这个函数,让它可以接受任意数量的参数? function createInstance(ofClass, arg1, arg2, arg3, ...
我想用简单的 C++ 语法创建一个简单的工厂方法: void *createObject(const char *str,...) { if(!strcmp("X",str)) retu
经过大约 10 个月的程序化 PHP 学习后,我现在正尝试着手研究基本的 OOP 原则和设计模式。这是一个爱好,我没有那么多时间去追求它,所以请原谅这个问题的水平很低。 我的网站(目前 100% 程序
我有一个简单的问题。 我如何编写一个工厂来定义使用 make() 或 create() 的关系,具体取决于原始调用 make() 还是 create()? 这是我的用例: 我有一个简单的工厂 /**
我正在尝试在延迟加载模块中提供 APP_BASE_HREF 注入(inject) token ,然而,工厂方法根本没有被调用。 在这里https://github.com/MaurizioCascia
我有以下 ast: import { factory as f } from 'typescript' const typeDeclaration = f.createTypeAliasDeclara
我是一名优秀的程序员,十分优秀!