倾听诺言

时间:2017-12-05 12:10:39

标签: node.js promise rxjs observable reactive-programming

我一直在阅读const Rx = require('rxjs/Rx'); Promise = require('bluebird'); let i = 0; function calculate() { return new Promise((resolve, reject) => { setInterval(() => { console.log(++i); resolve(i); }, 5000); }) } let source = Rx.Observable.fromPromise(calculate()); source.subscribe( next => { console.log(next, ' next '); }, err => { console.error(err) }, () => { console.log('done!'); } ) 。我读到的一件事是它能够像流一样倾听。我使用以下代码尝试了这个。

1
1 ' next '
done!
2
3

但它不像流一样工作。所以输出看起来像:

select count(*) from (select distinct a, extract(hour from time) from t where time >'2017-11-26 01:00:11' and time <'2017-11-26 05:00:00' and sensor_id=123)t;

我如何继续听取承诺?这是Observable真正解决的问题之一吗?

3 个答案:

答案 0 :(得分:2)

Observable.fromPromise被认为将Promise转换为Observable。因为promise只能解析一次,所以此流总是只输出1个项目。

您无法通过在其上包装流来增强承诺功能。如果promise只能产生1个值,那么在得到的observable中只会产生1个值。

在您的具体示例中,Observable.interval(n)n毫秒发出1个项目。另外,对于更加定制的观察:

Rx.Observable.create(obs => {
    let i=0;
    setInterval(() => {
        obs.next(++i);
    }, 1000);
});

当您创建一个observable时,您将获得一个Observer实例,该实例代表刚刚订阅了您的流的观察者。请注意,每个新观察者都将创建一个新的上下文(因此在我的示例中,每个观察者都将拥有他的i计数器。)

答案 1 :(得分:0)

您可以使用switchMap和interval:

let i = 0;

function calculate() {
    return Promise.resolve(++i)
}
//I reduce to the strictly necessary for the answer, the promise's resolve. 
//It's possible to have more things 

let source = Rx.Observable
    .interval(1000)
    .switchMap(() => calculate())

source.subscribe(
    next => {
        console.log(next, ' next ');
    },
    err => {
        console.error(err)
    },
    () => {
        console.log('done!');
    }
)

您可以在此处查看switchMap和间隔的文档:

演示:https://jsbin.com/nutukiyagi/1/edit?js,console

在这种情况下,您永远不会完成流,console.log(&#39;完成!&#39;)永远不会出现在控制台中

答案 2 :(得分:0)

来自with cte as (select emp_id,name,salary,cumulative_salary, sum(salary) over(partition by grp order by emp_id) as cumsum_sal from (select emp_id,name,salary,cumulative_salary,(row_number() over(order by emp_id)-1)/3 as grp from tbl ) t ) update cte set cumulative_salary=cumsum_sal 的文档:

  

如果Promise使用值解析,则输出Observable将该解析后的值作为下一个值发出,然后完成。

这准确描述了您所面临的行为。您应该使用generator functionRx.Observable.create来解决此特定问题。