【问题标题】:How to access a Set after asynchronous calls are complete异步调用完成后如何访问 Set
【发布时间】:2019-02-19 21:48:17
【问题描述】:

使用此代码,我可以正确添加到“MaterialCollectionSet”

let MaterialCollectionSet: Set<string> = new Set();

for(let data of SDE_REACTIONDATA) {

  this.ESI.ReturnsType_AtId(data.materialTypeID).subscribe((MaterialData) => {

    MaterialCollectionSet.add(MaterialData.name);

});

但是,尝试运行 代码

let MaterialCollectionSet: Set<string> = new Set();

for(let data of SDE_REACTIONDATA) {

  this.ESI.ReturnsType_AtId(data.materialTypeID).subscribe((MaterialData) => {

      MaterialCollectionSet.add(MaterialData.name);

}); 

console.log(MaterialCollectionSet);

将记录一个空集。

我知道这是因为异步调用发生在 console.log 在 for-of 循​​环之外被调用。

我的问题是,一旦 for-of 循​​环完成填充 Set,如何实际使用它?

【问题讨论】:

标签: angular typescript asynchronous callback


【解决方案1】:

我们可以使用forkJoin 等待所有请求

const requests$ = SDE_REACTIONDATA.map(data => this.ESI.ReturnsType_AtId(data.materialTypeID));

let MaterialCollectionSet: Set<string> = new Set();

forkJoin(requests$).subscribe(responses => {
  // Now you can access the `responses`;
  MaterialCollectionSet.add(responses.map(MaterialData => MaterialData.name));
})

或者正如@JB Nizet 建议的那样:

const requests$ = SDE_REACTIONDATA.map(data => this.ESI.ReturnsType_AtId(data.materialTypeID));

let MaterialCollectionSet: Set<string> = new Set();

merge(requests$).subscribe(
  MaterialData => MaterialCollectionSet.add(MaterialData.name),
  null, // error handler
  () => console.log(MaterialCollectionSet) // complete
)

正确的解决方案取决于您的需求。

【讨论】:

  • 感谢您的回复!多参数'.subscribe'按顺序执行?我以前没有使用过这种语法。所有订阅都有完成回调的参数吗?还是只是合并式订阅。
  • forkJoin 就像 Promise.all,在所有 observables 完成后发出。 merge 在每个 observables 上发出。如果订单很重要,请查看concat 。每个订阅has(下一个,错误,完成)回调。
猜你喜欢
  • 1970-01-01
  • 2018-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-10
  • 2021-01-27
  • 2017-01-03
  • 1970-01-01
相关资源
最近更新 更多