【问题标题】:Serialise observable next function calls序列化可观察的下一个函数调用
【发布时间】:2018-11-07 20:42:55
【问题描述】:

考虑以下 Typescript / rxjs 代码:

import { range } from 'rxjs'; 

range(1, 5).subscribe(async (num) => {
  await longLastingOperation(num);
})

function longLastingOperation(num) {
  console.log('starting', num);

  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('done with', num);
      resolve();
    }, Math.random() * 1000);
  });
}

每个发出的值都会触发一个随机持续时间的持久操作。控制台输出是不可预测的,看起来类似于:

starting 1
starting 2
starting 3
starting 4
starting 5
done with 2
done with 5
done with 1
done with 4
done with 3

现在,我想为每个发出的值“序列化”执行持久操作。例如,我希望 longLastingOperation(2) 在开始之前等待 longLastingOperation(1) 完成。

我希望每次都得到一个看起来完全一样的输出:

starting 1
done with 1
starting 2
done with 2
starting 3
done with 3
starting 4
done with 4
starting 5
done with 5

如何使用 rxjs 和 observables 实现这一目标?

【问题讨论】:

    标签: javascript typescript rxjs


    【解决方案1】:

    考虑在每个longLastingOperation(num) 调用上使用concatMap 运算符将响应包装在 Observable 中并按顺序订阅结果:

    range(1, 5)
    .concatMap((num) => {
      return Observable.fromPromise(longLastingOperation(num));
    })
    .subscribe(res => {
      console.log(`End working on ${res}`) // Shall be ordered here
    })
    

    这是文档参考:
    http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-concatMap

    这是我在这个主题上的一些额外工作:
    https://www.linkedin.com/pulse/rx-map-misleading-marbles-tomasz-budzi%C5%84ski/

    【讨论】:

    • 很高兴我能提供帮助。供您参考,请查看reactivex.io/rxjs/manual/overview.html#operatorsChoose an operator 部分。它会在 95% 的情况下指出您需要的运算符。不幸的是,RxJS 6 在它的文档站点上没有这个特性:(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多