资讯专栏INFORMATION COLUMN

RxJS Observables vs Promise 之简单对比

klivitamJ / 1992人阅读

摘要:最近在学习,它是使用的响应式编程的库,它使编写异步或基于回调的代码更容易。返回的是一个对于指定的。发送请求使用了,虽然了多次,但是仅发送一次请求,了结果。中有一些操作符可以让监听强制为异步的方式,例如。

最近在学习RxJS,它是使用 Observables 的响应式编程的库,它使编写异步或基于回调的代码更容易。

下面主要介绍Observables 与 promise的不同点。

单值与多值
const numberPromise = new Promise((resolve) => {
    resolve(5);
    resolve(10)
});

numberPromise.then(value => console.log(value));

// 输出 只会有 5

下面改写为observables的写法,使用 next 替代 promise 的 resolve, 用subscribe 取代then来订阅结果。

const Observable = require("rxjs/Observable").Observable;

const numberObservable = new Observable((observer) => {
    observer.next(5);
    observer.next(10);
});

numberObservable.subscribe(value => console.log(value));

// 输出 5 10

observable是可以连续订阅的,这个和promise的区别很大。平时我们遇到的可能大多数都是一个请求一个响应的这种情况,但是我们也会存在一些情况:

setInterval,需要resolve多个值

webSockets

DOM events

const numberObservable = new Observable((observer) => {
      let i = 0;
      setInterval(() => {
          observer.next(i++);
      }, 1000);
});
    
numberObservable.subscribe(value => console.log(value));    
// 输出 0 1 2 3 4 5
代码执行顺序
const promise = new Promise((resolve) => {
    console.log("promise call")
    resolve(1);
    console.log("promise end")
})

// 执行这段代码 promise call 和 promise end 会立即执行
const observable = new Observable(() => {
    console.log("I was called!");
});

// 此时并没有console

// 只有 observable.subscribe(); 这个时候 I was called!才会被打印出来。

上面两段代码就对比可以发现Observables是lazy的,只有当有人去订阅(subscribe)的时候Observables才会真正的被执行。

如果上方setInterval的函数写在promise里面,但是没有promise.then之类的函数就会造成资源的浪费,而在observable里面,不订阅连内存都不会分配。

不能取消 & 能取消

promise默认是不能取消的,可以使用promise的实现库 bluebird 来实现。bluebird是完全兼容promise并且添加了一些有用的方法。

const Observable = require("rxjs/Observable").Observable;

const observable = new Observable((observer) => {
    let i = 0;
    const token = setInterval(() => {
        observer.next(i++);
    }, 1000);
  
    return () => clearInterval(token);
});

const subscription = observable.subscribe(value => console.log(value + "!"));

setTimeout(() => {
    subscription.unsubscribe();
}, 5000)

// 结果

0!
1!
2!
3!

这个地方需要注意的是, subscribe 返回的不是一个Observable! 这就是说不能和promise一样链式的subscribe。subscribe返回的是一个对于指定observable的 Subscription。他只有一个方法可以调用,就是unsubscribe。

单个订阅&多个订阅

promise 是比较激进的,在一个promise被创建的时候,他就已经执行了,并且不能重复的被执行了。

let time;
const waitOneSecondPromise = new Promise((resolve) => {
    console.log("promise call")
    time = new Date().getTime();
    setTimeout(() => resolve("hello world"), 1000);
});

waitOneSecondPromise.then((value) => {console.log( "第一次", value, new Date().getTime() - time)});

setTimeout(() => {
    waitOneSecondPromise.then((value) => {console.log("第二次", value, new Date().getTime() - time)});   
}, 5000)

// 输出结果是 promise call
第一次 hello world 1007
第二次 hello world 5006

上面这个例子中,我创建了一个promise,他是立即执行的setTimeout,所以在第一个then函数中打印时间间隔是约等于 1s,这个是符合我们预期的,希望能在1s后获取到promise的返回值 。 第二个then函数是在 5s之后执行的,第二次hello word 和promise的开始时间差约为5s。因为在该promise创建的1s后已经resolve,此时就直接调用then函数,不会延时1s执行。因为promise是只会执行一次。

那么再来看obsrvables

const Observable = require("rxjs/Observable").Observable;

let time;
const waitOneSecondObservable = new Observable((observer) => {
    console.log("I was called");
    time = new Date().getTime();
    setTimeout(() => observer.next("hey girl"), 1000);
});

waitOneSecondObservable.subscribe((value) => {console.log( "第一次", value, new Date().getTime() - time)});

setTimeout(() => {
    waitOneSecondObservable.subscribe((value) => {console.log( "第二次", value, new Date().getTime() - time)});
}, 5000)

// 输出
I was called
第一次 hey girl 1003
I was called
第二次 hey girl 1003

这个就是我们希望的结果,他在每一次订阅的时候都会重新去执行被监听的函数,不论什么时候想要用这个函数,只需要重新 subscribe 一下就可以。

用observable已经可以实现多次订阅,但是这有时候可能不能符合我们的业务场景,在http请求中,我们可能希望只发一次请求,但是结果被多个订阅者共用。 Observables 本身没有提供这个功能,我们可以用 RxJS 这个库来实现,它有一个 share 的 operator。

const waitOneSecondObservable = new Observable((observer) => {
    // 发送http请求
});

const sharedWaitOneSecondObservable = 
    waitOneSecondObservable.share();

sharedWaitOneSecondObservable.subscribe(doSomething);

sharedWaitOneSecondObservable.subscribe(doSomethingElse);

// 使用了share,虽然subscribe了多次,但是仅发送一次请求,share了结果。
一直是异步 & 可能是异步
const promise = new Promise((resolve) => {
    resolve(5);
});

promise.then(value => console.log(value + "!"));

console.log("And now we are here.");

// 
And now we are here.
5!

虽然在promise里面 resolve了一个同步的东西,但他还是会先执行完代码。

const Observable = require("rxjs/Observable").Observable;

const observable = new Observable((observer) => {
    // observer.next(5);
    setTimeout(() => {
        observer.next(5);
    })
});

observable.subscribe(value => console.log(value + "!"));
console.log("And now we are here.");

// 
这个如果是直接next 5,则输出是  5! -> And now we are here.
采用setTimeout next 5, 则相反  And now we are here.-> 5!

promise一直是异步, Observables则比较灵活,是否为异步得根据自己的函数来定,这点也比较危险。rxjs中有一些操作符可以让监听强制为异步的方式,例如 observeOn。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/7261.html

相关文章

  • [译] RxJS文档02—— Observable 可观察量

    摘要:原文可观察量是一种能惰性推送的集合,他可以包含多个值。是一种惰性计算方式,会在迭代中同步的返回到无限个可能的话返回值。使用一种处理方法,最终可能会或可能不会返回一个值。无论是同步方式还是异步方式,都可以择其一来传递返回值。 原文:http://reactivex.io/rxjs/manu... Observable 可观察量是一种能惰性推送的集合,他可以包含多个值。下面的表格对比了推送...

    A Loity 评论0 收藏0
  • Rxjs 响应式编程-第二章:序列的深入研究

    摘要:接下来,我们将实现一个真实的应用程序,显示几乎实时发生的地震。得到的由表示,其中包含和的合并元素。如果不同同时传出元素,合并序列中这些元素的顺序是随机的。是操作序列的强大操作符。但是的方法仍在运行,表明取消并不会取消关联的。 Rxjs 响应式编程-第一章:响应式Rxjs 响应式编程-第二章:序列的深入研究Rxjs 响应式编程-第三章: 构建并发程序Rxjs 响应式编程-第四章 构建完整...

    姘搁『 评论0 收藏0
  • 从观察者模式到迭代器模式系统讲解 RxJS Observable(一)

    摘要:是的缩写,起源于,是一个基于可观测数据流结合观察者模式和迭代器模式的一种异步编程的应用库。是基于观察者模式和迭代器模式以函数式编程思维来实现的。学习之前我们需要先了解观察者模式和迭代器模式,还要对流的概念有所认识。 RxJS 是 Reactive Extensions for JavaScript 的缩写,起源于 Reactive Extensions,是一个基于可观测数据流 Stre...

    notebin 评论0 收藏0
  • Rxjs 响应式编程-第一章:响应式

    摘要:响应式编程具有很强的表现力,举个例子来说,限制鼠标重复点击的例子。在响应式编程中,我把鼠标点击事件作为一个我们可以查询和操作的持续的流事件。这在响应式编程中尤其重要,因为我们随着时间变换会产生很多状态片段。迭代器模式的另一主要部分来自模式。 Rxjs 响应式编程-第一章:响应式Rxjs 响应式编程-第二章:序列的深入研究Rxjs 响应式编程-第三章: 构建并发程序Rxjs 响应式编程-...

    songze 评论0 收藏0
  • 翻译连载 | 第 10 章:异步的函数式(下)-《JavaScript轻量级函数式编程》 |《你不知

    摘要:而数组里则是为每一个值运行一次映射函数,无论这个值何时加入,然后把它返回到里。上一章翻译连载第章异步的函数式上轻量级函数式编程你不知道的姊妹篇原创新书移动前端高效开发实战已在亚马逊京东当当开售。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson-《You-Dont-Know-JS》作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 ...

    魏明 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<