【问题标题】:Understanding the results of Promise vs Obervables了解 Promise 与 Observables 的结果
【发布时间】:2020-01-14 20:43:53
【问题描述】:

承诺:

实施

  getDataPromise(): any {
    let promise = new Promise((resolve, reject) => {
      resolve([
        { brand: 'iPhone', model: 'Xmax', price: '$1000' },
        { brand: 'Samsung', model: 'S10', price: '$850' }
      ]);
    });
    return promise;
  }

// promise call
getDataPromise.then((data) => { 
    console.log("Result: ", data);
});

结果是一个数组:

Result: [
  { brand: 'iPhone', model: 'Xmax', price: '$1000' },
  { brand: 'Samsung', model: 'S10', price: '$850' }
]

可观察

实施

  import { from } from 'rxjs';

  getDataObservable(): any {
    return from([
      { brand: 'iPhone', model: 'Xmax', price: '$1000' },
      { brand: 'Samsung', model: 'S10', price: '$850' }
    ]);
  }

// observable call
getDataObservable().subscribe((data) => {
    console.log("Result: ", data);
});

结果依次是2个对象:

Result: { brand: 'iPhone', model: 'Xmax', price: '$1000' }
Result: { brand: 'Samsung', model: 'S10', price: '$850' }

试图了解其中的区别,浏览了在线资料,但仍然无法回答以下 2 个问题。

  • 为什么结果不同?

  • 如何从 observable 中获取结果为数组(类似于 promise 中的)?

【问题讨论】:

    标签: angular typescript promise rxjs observable


    【解决方案1】:

    一个承诺结束 - 它解决 (then) 或拒绝 (catch) 就是这样。一个可观察的流值直到它结束(很多时候,它永远不会结束,你只是“失去兴趣” - 或者取消订阅值流)。

    我喜欢 keypress 示例 - 如果您使用基于 keypress 事件的 promise 来解决/拒绝,那么您将只听“下一个”按键,然后您必须创建一个新的 promise 来听下一个,依此类推。

    使用 observables,您只需要创建一个,它就会不断地向您传输值,直到您不再感兴趣(取消订阅)。

    Promise:
    
    const subscribeToKeyPress = () => {
      let resolve;
      document.addEventListener('keydown',function listener(e) {
          resolve(e);
          // unsubscribe from the event listener, otherwise you've got a memory leak
          document.removeEventListener('keydown',listener);
      });
      return new Promise(r => resolve = r);
    }
    
    subscribeToKeyPress().then(e => {
      // done, never to receive another result
    });
    
    #####
    Observable:
    
    const subscribeToKeyPress$ = () => fromEvent(document,'keypress);
    
    const unsubscribe = subscribeToKeyPress$().subscribe(e => {
      // called continually on each keypress until you unsubscribe
    });
    
    unsubscribe(); // your callback function won't be called anymore, if you don't call unsubscribe when you're done, you've got a memory leak
    
    #####
    Callback Function - the simplest "observable"
    
    const subscribeToKeyPress = callback => {
       const fn = e => callback(e); // this function will get called over and over until you unsubscribe
       document.addEventListener('keypress',fn);
       return () => document.removeEventListener('keypress',fn);
    }
    
    const unsubscribe = subscribeToKeyPress(e => {
      // called continually on each keypress until you unsubscribe
    });
    
    unsubscribe(); // your callback function won't be called anymore, if you don't call unsubscribe when you're done, you've got a memory leak
    

    如何从 observable 中获取结果为数组(类似于 as 承诺)?

    查看https://www.learnrxjs.io/operators/utility/topromise.html

    也与toPromise相关:https://github.com/ReactiveX/rxjs/issues/2536

    如果您的 observable 没有“完成”(如按键监听器)toPromise 将永远无法工作(除非您首先 pipe(take(1)),但这对于新手来说很多,没有冒犯,但来自承诺世界, observables 真的很难理解——根据我的个人经验——直到它们不再存在)。

    【讨论】:

    • 感谢您解释基础知识。
    【解决方案2】:

    promise 和 observables 都是异步的。无论哪种方式,您都需要分别处理它们

    但是,from 运算符将您的数组作为值序列发出,因此您会看到结果。

    如文档所述,from 运算符

    将数组、promise 或 iterable 转换为 observable。

    这就是getDataObservable 将对象数组打印为不同序列的原因。

    如果您希望将它们作为单个序列返回,请改用of 运算符。

    在一个序列中发出可变数量的值,然后发出一个完整的 通知。

    import { of } from 'rxjs';
    
    const getDataObservable = () => {
      return of([
        { brand: 'iPhone', model: 'Xmax', price: '$1000' },
        { brand: 'Samsung', model: 'S10', price: '$850' }
      ]);
    }
    
    getDataObservable().subscribe((data) => {
        console.log("Result: ", data);
    });
    

    这是demo

    【讨论】:

      【解决方案3】:

      只是因为from:

      对于数组和可迭代对象,所有包含的值都将作为一个序列发出!

      如果你成功了:

      from([[
        { brand: 'iPhone', model: 'Xmax', price: '$1000' },
        { brand: 'Samsung', model: 'S10', price: '$850' }
      ]]);
      

      那么结果也是一样的。

      observable 和 promise 的区别:

      但是 observable 和 promise 之间有一个关键的区别:

      1. 如果你在事件之后注册一个 observable,那么已经发生的事件将不会发生任何事情(只会收到未来事件的通知)。对于一个承诺,then() 仍然会生效。
      2. 对于 observable,您可以继续收到相同类型事件的通知。对于一个 Promise,一旦它被解决(解决或拒绝),那么它就完成了,仅一次。

      【讨论】:

        猜你喜欢
        • 2018-12-25
        • 1970-01-01
        • 2014-07-16
        • 2018-02-09
        • 1970-01-01
        • 2020-05-07
        • 2012-01-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多