据我了解,以下是解决异步编程工作流的技术:
更新的方法:
我们现在正在远离回调&对这些新方法的承诺。我目前理解的是 - Async / Await更像是在ES2015生成器之上更清晰的抽象。
我无法理解的是Observables和Generators之间的概念差异。我已广泛使用它们并且没有使用它们。
令我困惑的是Observables和Generators的用例。我得出的结论是,他们最终解决了同样的问题 - 异步性。只有我看到的潜在差异是生成器固有地为代码提供命令式语义,而使用Rxjs的Observable似乎提供了反应范式。但就是这样吗?
这应该是Observable和Generator之间选择的标准吗?有什么优点和缺点。
我错过了大局吗?
同样Observable最终制作成未来的Ecmascript,Promises(带有可取消令牌)/ Observable / Generators会相互竞争吗?
答案 0 :(得分:14)
Observable推动变化,因此可观察的,而不是对其作出反应的功能是可控制的。另一方面,生成器要求您从中提取值。因此,对新值作出反应的函数决定何时为新值做好准备。
我在使用observables时遇到了背压问题,但是对于生成器,你可以根据需要放慢速度。
编辑:最后一个问题。承诺只是只发出一次的可观察物,所以我认为它们不会相互竞争。我认为真正的战斗将是async / await vs observables,async / await有一个良好的开端,并且已经在C#(现在是Node.js)。但是可观察到的是那种甜美的FRP感觉,而且功能性编程非常酷,所以我认为他们最终都会有很大的思想共享。
Edit2:AndréStaltz,Cycle.js和xstream的作者,以及Rx.js的撰稿人,写了一篇关于生成器和Observable如何关联的伟大的文章(2018-01-31)。特别是,他展示了他们如何从一个共同的基类继承。
现在消费者可以是一个倾听者(“观察者”)或者一个拉动者,它取决于消费者是否会拉动生产者。生产者可以是可听的(“可观察的”)或Pullable(“可迭代的”),无论是主动发送数据还是仅按需发送数据,都取决于生产者。如您所见,消费者和生产者都是相同类型的简单功能:
(num,payload)=>空隙
因此,我们构建的任何运算符都可以用于反应式编程或可迭代编程,只是因为这两种模式之间的界限变得模糊,而且它不再是可观察对象与迭代对象,它只是关于生产者和消费者之间数据的转换。 / p>
我建议您阅读[link]。本文介绍了“Callbags”,这是一个用于反应式和可迭代编程的回调规范。他实现了该规范,以便为可迭代和反应式编程提供a tiny library。为了吸引您阅读文章并查看库,以下是基于他介绍的规范的7kb库中的一些示例:
反应式编程示例
从每秒钟滴答的时钟中挑选前5个奇数,然后开始观察它们:
const {forEach, interval, map, filter, take, pipe} = require('callbag-basics');
pipe(
interval(1000),
map(x => x + 1),
filter(x => x % 2),
take(5),
forEach(x => console.log(x))
);
// 1
// 3
// 5
// 7
// 9
可重复编程示例
从一系列数字中挑选其中的5个并将它们除以4,然后开始逐个拉出这些数字:
const {forEach, fromIter, take, map, pipe} = require('callbag-basics');
function* range(from, to) {
let i = from;
while (i <= to) {
yield i;
i++;
}
}
pipe(
fromIter(range(40, 99)), // 40, 41, 42, 43, 44, 45, 46, ...
take(5), // 40, 41, 42, 43, 44
map(x => x / 4), // 10, 10.25, 10.5, 10.75, 11
forEach(x => console.log(x))
);
// 10
// 10.25
// 10.5
// 10.75
// 11
答案 1 :(得分:1)
我知道这个问题是在 2016 年发布的,其中 generator
仍然同步使用。
不过,我认为今天一个更有趣(合适)的问题是 async generator
和 reactive observable
或 reactive programming
之间的区别。请允许我离题。
在下文中,我将使用:
A
代表 async/await, promise
等B
代表 async generator
C
代表 reactive observable
。首先,它们都旨在处理 async
数据。重要的是细节。
如果我们有一个有限且小的 async
数据源,例如单个 HTTP 请求,磁盘上只有几 KB 的数据。然后 A
获胜,简单明了。
当数据源变得无限(例如用户点击)或太大而无法保存在内存中时,A
将无法正常工作,因为我们很快就会遇到意外的复杂性(首先要处理背压) . B
和 C
总体上都很出色,因为它们都以一种或另一种方式提供背压设施。
然后,当数据源开始需要缓冲、去重、去抖动、与其他数据源合并/交错等时,C
获胜,因为许多库将提供通用运算符来帮助处理常见的流问题。一个示例用例是阻止用户在短窗口(例如 5 秒)内发送垃圾评论。
这是否意味着C
总体上比B
好?
在我看来,没有。尽管 C
更通用,但 B
更简单、更灵活,并且与语言的集成更好(例如 for await ... of
)。而且它几乎不需要您按照 C
的要求更改整个编程范式。
答案 2 :(得分:0)
您可以将rxjs observable视为异步生成器,即生成promises的生成器。仅仅因为在我们调用.next(与常规生成器相反)时,内容不能保证准备就绪